Changing the light level of a block

Discussion in 'Plugin Development' started by EmpyrealHell, Feb 27, 2011.

Thread Status:
Not open for further replies.
  1. Offline

    EmpyrealHell

    So I decided today that I wanted to try and make a server mod for this game. Bukkit seemed like the way to go and it has been relatively smooth sailing so far, but I've run into a snag. I want to be able to alter the light of a block. I've seen this done with mods like torchburn and flashlight, but I can't seem to find the function that allows this.

    To be more specific, I want to be able to increase or decrease the level of light on a block, regardless of depth. Counteracting the sunlight seems difficult without placing a block over it, and even that workaround is useless when dealing with subterranean areas.

    Any help would be much appreciated, even something as simple as a function name or the appropriate object to be looking at would be outstanding.

    If it matters I'm writing this mod in Java using Eclipse.
     
  2. Offline

    Edward Hand

    You have not chosen a simple first plugin. (It might be better to start with something easier, since this requires a quite hack-ish solution).

    You need to interface with craftbukkit and the minecraft base classes themselves (which isn't entirely supported by the bukkit team).

    If you still want to know how:
    Code:
    CraftWorld cWorld = (CraftWorld)theWorld;
    cWorld.getHandle().b(EnumSkyBlock.BLOCK, X, Y, Z, lightLevel)
    where:
    theWorld = a reference to the world you want to change the light level in​
    X,Y,Z = the (integer) coordinates of the block to change the light level of​
    lightLevel = a value between 0 (completely dark) and 15 (fully lit)​

    EDIT: fixed an error (misplaced .)
     
  3. Offline

    EmpyrealHell

    I'm not new to programming, just new to modding this particular game; I feel up to the challenge, and that is exactly what I was looking for.

    Outstanding, thanks for the quick response.

    Edit: Fixed a run-on
     
  4. Offline

    Ryan Carretta

    Hi Empyreal - Edward has already kindly told you all that you probably need to know. However, if I could contribute further...

    Bear in mind that light levels decrease by 80% for each block you get from a light source. As such, it's never completely dark (0).

    Also, I put in a pull request for Bukkit/CraftBukkit for Block.setLightLevel - don't know if it will be accepted:
    https://github.com/Bukkit/Bukkit/pull/136
    https://github.com/Bukkit/CraftBukkit/pull/168
     
  5. Offline

    Afforess

    I believe the problem with setting the light level is that the next instance the game rechecks the light level, it will override your change, unless you keep changing it back. This happens often, especially outside.
     
  6. Offline

    weasel5i2

    I also need to figure this out so I can make the lily pads stay put. :p
     
  7. Offline

    4am

    Check out the Flashlight source - although it's no longer working in newer CraftBukkit builds. Not sure if this is due to multiworld support missing or if something low-level was altered that makes this not feasable/possible anymore. It has been requested to the Bukkit team by several people, including the author of flashlight.

    I can't wait for the day when Minecraft supports multicolor lighting :) The red glow of a redstone torch seems like it would be so awesome looking...
     
  8. Offline

    narrowtux

    Maybe they should add a new Event to the BlockListener then. For example "onBlockLightChange". The corresponding Event class should roughly look like this:
    Code:
    class BlockLightChangeEvent extends BlockEvent{
        int oldLightLevel;
        int newLightLevel;
        public int getOldLightLevel()
        {
            return oldLightLevel;
        }
        public int getNewLightLevel()[
        {
            return newLightLevel;
        }
        public void setNewLightLevel(int level)
        {
            newLightLevel = level;
        }
    }
    
    After the event has been sent, the hook should take the newLightLevel-Value for the light value that will be set after that.
    This would enable light-changing plugins to adjust the lights after the server has recalculated the light for that specific block.
     
  9. Offline

    narrowtux

    Maybe I found the proper location to hook light level changes:
    Look in net.minecraft.server.Chunk.java, line 312:
    Code:
         
        public void a(EnumSkyBlock enumskyblock, int i, int j, int k, int l) {
            this.o = true;
            if (enumskyblock == EnumSkyBlock.SKY) {
                this.f.a(i, j, k, l);
            } else {
                if (enumskyblock != EnumSkyBlock.BLOCK) {
                    return;
                }
    
                this.g.a(i, j, k, l);
            }
        }
    
    Chunk.f and Chunk.g seem to store the light level values for each block in that chunk.
    Chunk.f is for Sky-Light-level (i think) and Chunk.g is for the actual block light level. We should hook before this.g.a(i,j,k,l); with the BlockLightLevelChangeEvent.
     
  10. Offline

    Sammy

    @Edward Hand can I ask you a personal question ? are you in a major in computer science or something like that?
    Cause' I'm not seeing how do you come up with all those "hack-ish solutions" if you are a self learned guy like most of us :p
    Can you give me some tips (books or tutorials) how to really understand obfuscated code and those other things? or is it a practice type of thing ?

    I really have respect for you man, you take a lot of time helping pour ninja wannabes like us :rolleyes:
     
  11. Offline

    Edward Hand

    Physics actually, but I suppose the logic is similar - its all just seeing the links connecting everything together.
    I'd never tried deciphering obfuscated code (or java code of any kind) before I found minecraft. It was months ago, before de-obfuscated versions of the code existed, so I had to do it all myself. I just spent a couple of days almost non stop reading through the code. Found every invulnerability in the book pretty quickly. By now the obfuscated code is almost second nature.

    If you want to get into it, you will find the following things useful:
    • A general understanding of how the major parts of the minecraft server plug together.
    • A full copy of the code (not just the snippets on github) - decompile the craftbukkit snapshot with jd-gui for that
    • Import the decompiled source into eclipse - eclipse is great for its ability to search everything and the 'open call heirarchy' and 'open deceleration' options in the right-click menu come in really useful for seeing what's calling what.
    For understanding the code, just going through it is the best way.
    This tool will decompile and de-obfuscate the vanilla server (and deobfuscates a fair bit more than bukkit) so makes easier reading:
    http://www.minecraftforum.net/viewtopic.php?f=25&t=58464

    If you want to find some functionality in the code, there are two possible ways of thinking:
    1. What in the game would trigger this functionality to occur normally?
    2. What end affect does this functionality have?
    and that's where general understanding of the structure comes in useful.

    For example, if you want to know what happens when the text on a sign gets changed, starting where the Packet130SignChange packet is received from the client in the NetServerHandler class is a good place to start. From there, you can follow what other functions get called until you find what you're looking for.

    On the other hand, if you want to find the code that effects sleeping, perhaps finding the boolean variable in the EntityPlayer class that holds whether the player is sleeping would be a good place to start. Right clicking on it in eclipse and selecting 'open call hierarchy' shows you every class and function that alters/calls that variable. One of them has to be useful.

    Just start at either end and follow the links until you find the function or variable you need.

    Is this helping?
     
  12. Offline

    Afforess

    Awesome! Any chance you could submit a pull request to Bukkit & CraftBukkit to add that in?
     
  13. Offline

    Sammy

    It really helped a lot, I don't use eclipse I use NetBeans but I know what you are talking about :)
    You should do a topic with what you told me.
    Thanks for taking the time to write it, awesome work as always my friend !
     
  14. Offline

    narrowtux

    I didn't set up a working compile for Bukkit yet, will have to try to compile bukkit. When it works, I will play around with the event.
     
  15. Offline

    flAked

    Any news on this topic?

    I made a proof-of-concept after analyzing all light-changing functions in the original code that turns a wool-block into a 10 block radius super-light.

    Destroying or placing new blocks in that radius triggers a relight with massive lag. My theory is that besides calling b() another call is needed to store the information for the next light check.

    How do torches do things differently?
     
  16. Offline

    narrowtux

    I tested my hook, but realized that this just creates massive lag and doesn't change anything in the lightning.
     
Thread Status:
Not open for further replies.

Share This Page