-
Posts
274 -
Joined
-
Days Won
5
Everything posted by imacatlolol
-
[1.15] Save data to world using WorldSavedData
imacatlolol replied to KidKoderMod033109's topic in Modder Support
Can't you? I believe the SERVER config type will do exactly what is desired, unless the javadocs are misleading me. -
I'll say it again, this time with a little more clarity, override onBlockClicked to activate it when it's left clicked. There's no built-in feature for detecting side collisions in the way you want. Maybe you could have it detect nearby entities and activate that way. Use something like World#getEntitiesWithinAABBExcludingEntity for that.
-
[1.14.4] Load custom resources outside the jar
imacatlolol replied to Eisenpaulchen's topic in Modder Support
Since playing arbitrary sounds isn't a normally supported feature, there's quite a lot of work to do to make things behave properly. All those "func_######" methods are obfuscated, so the best way to learn what they are is to understand what is being put into them. For example, SoundSource#func_216422_a(float) doesn't have any clear purpose, but by looking at its usages in vanilla code I can find out that it sets the pitch of the sound source. Here's a rough explanation of how sounds are played, based on what you're trying to do: Something creates an instance of an ISound. Most things use an instance of SimpleSound since it contains all sorts of useful properties. This ISound instance is then passed into SoundHandler#play(ISound), which is then passed SoundEngine#play(ISound). This is where the sounds get played. A whole bunch of stuff happens here. Forge runs some event hooks, a few values are validated, subtitles get activated, etc. You can ditch most of this for your system, but I recommend keeping all of it and working around it in order to keep things as close to vanilla as possible. Now, in the else part of the if(sound == SoundHandler.MISSING_SOUND) branch, this is where things get interesting, and confusing. From here, variables and methods are mostly obfuscated and arbitrary, which makes things hard to read. When reverse engineering this process, you may want to copy the code elsewhere and change the variable names as you go to make things easier to understand. Adding comments to obfuscated method calls can help remind you what those methods do when you figure them out. Now here's the biggest hurdle to get over: channelmanager$entry. As you can see, channelmanager$entry is a channel created by the ChannelManager in SoundEngine. In order to play your own arbitrary sounds, you're going to need this ChannelManager instance. Trouble is, the field is private. You have two major options here. Use reflection to make the ChannelManager field in SoundEngine accessible. This isn't too hard, but you should have a very good understanding of how reflection works in Java before doing this since reflection can be dangerous. Use an access transformer to make the field accessible through Forge. I think this is the best solution of the two. Like reflection, you should learn how these work yourself to make sure you fully understand what you're doing, since this tool can also be dangerous. After channelmanager$entry has been configured from data in the ISound and its Sound (confusing, I know) about pitch, location, etc, it's time to actually play the sound! It has to do slightly different things if the sound is being streamed or not. Because we're working with a FileInputStream, I'm going to assume the sound will be streamed. First, AudioStreamManager#func_217917_b(ResourceLocation) is run. This supplies an IAudioStream by turning a ResourceLocation into an OggAudioStream. You can create an OggAudioStream from any InputStream, so try doing that with your FileInputStream! Will it work? No idea! I haven't tested it myself. Then, it plays the IAudioStream through the configured channelmanager$entry by calling SoundSource#func_216433_a(IAudioStream) followed by SoundSource#func_216438_c(). Congratulations, if you did everything right, you will have just played a sound from a file! This is about as close as I can get without directly spoon-feeding code or teaching basic Java. If people who are more experienced than me would like to improve any part of my explanation (or get rid of it, if it's too much hand-holding), it would be much appreciated. -
Render an image based on camera position
imacatlolol replied to Pacmandevil's topic in Modder Support
Check out ScreenShotHelper to see how screenshots are made. Thankfully it's a pretty painless process there. You may have to transfer pixel data from a NativeImage to a BufferedImage to do more complex image editing operations, however. I'd need to experiment with it to figure out the exact method for that. As for your concerns: Sadly I don't know of any clean workarounds for texture packs. Shaders and other client-side graphical mods would also be hard to work around. The process for any such workaround would certainly be way out of my skill set. To take a screenshot without the hud, use RenderGameOverlayEvent.Pre filtered by the ALL type and run the code there. It will also work when an overlay screen (like the inventory or pause menu) is being displayed since the event triggers before they render. You may want to use a higher event priority to ensure your code is run before other mods' code. -
[1.15] Save data to world using WorldSavedData
imacatlolol replied to KidKoderMod033109's topic in Modder Support
Just do what @Animefan8888 said. Save the data in the list using a ListNBT with the write method, then read it back using the read method. Don't forget to call markDirty when the data changes in order to have it actually save. -
[1.14.4] Load custom resources outside the jar
imacatlolol replied to Eisenpaulchen's topic in Modder Support
That's not a basic feature provided by Forge to my knowledge, but it is certainly possible. Loading files outside of the jar can be achieved using basic Java. Read up on FileInputStream. In order to use it, you can learn how the game plays sounds by exploring AudioStreamManager and SoundEngine among other related classes. -
[Solved] Where can I find the 1.15.2 Key values for keybinding?
imacatlolol replied to ultra_reemun's topic in Modder Support
You can find keycodes used by LWJGL in the GLFW class now. This has some more info on migrating away from the Keyboard class, if you're interested (not necessary for modding at all, but may be useful for learning about LWJGL). -
Deferred Registry BlockItem Current Method?
imacatlolol replied to BaconBombing's topic in Modder Support
Doesn't seem to be anything wrong to me... Where are you calling those init functions for these classes? -
Deferred Registry BlockItem Current Method?
imacatlolol replied to BaconBombing's topic in Modder Support
The block being used by your BlockItem is returning null in its registry object, and therefore "not present", when it goes to register the item. Please show your block registration code. -
Encountered a error during the load_registries event phase
imacatlolol replied to Daynerat's topic in Support & Bug Reports
Did you make sure to include Immersive Portals' dependencies? Check their mod page to make sure you have everything you need. -
Well, here's a couple ideas to try: To get rid of the roof bedrock you can override getBedrockRoofHeight to 0 in NetherGenSettings. After that, try making your own CaveWorldCarver that works the same as NetherCaveWorldCarver, but with a higher maximum height so that it breaks through the top. No idea if it'll work like you want, but it's worth trying. Experimentation is generally a good way to go.
-
That's a bit tougher, I don't actually know the best way to do that myself. One option would be to use inventoryTick; Check if the tags are present, and put them in if not. I'm sure someone who understands the system better than me could come up with a solution that isn't so hacky.
-
Don't create a new ItemStack at the end, use the one you made before.
-
[Solved] [1.15.2] Problems setting creepers powered
imacatlolol replied to SrGnis's topic in Modder Support
Don't create your own POWERED property, the creeper entity won't know what to do with it. You should either go back to NBT if that was working before, or use reflection/access transformers to access the actual POWERED property in the creeper entity class. -
Can I register custom AI to vanilla fish mobs?
imacatlolol replied to Kiljaeden053's topic in Modder Support
You can modify mob AI by subscribing to EntityJoinWorldEvent. -
Just a heads up, running your addTags method in the item constructor is pointless, unless you're doing it to test it. Anyways, onCreated only fires when an item is crafted, which is why it's not working for you. You want to use fillItemGroup to change the stack in the creative tab.
-
[1.15.2] Replace water in nether with lava
imacatlolol replied to RobinCirex's topic in Modder Support
Oh dang, that's become so second-nature to me that I didn't even notice! -
[1.15.2] Replace water in nether with lava
imacatlolol replied to RobinCirex's topic in Modder Support
If you want to prevent water from vaporizing, set doesWaterVaporize to false in the dimension's constructor method. Additionally, you should really be using DimensionManager's register methods for the sake of compatibility.