Jump to content

Tschallacka

Members
  • Posts

    90
  • Joined

  • Last visited

Everything posted by Tschallacka

  1. @Draco18s for the metadata it's jus the normal leaves variety, the different states that actually are needed for the model are defined by getActualState. works quite well actually and looks pretty :-) @Choonster I'll see if I can fiddle around with the statemapper :-) thanks for pointing out where to look.
  2. I tried following the tutorial on https://mcforge.readthedocs.org/en/latest/blockstates/forgeBlockstates/ but for some reason I cant seem to get it right, or understand how to implement it in my case. I keep getting the messages that forge cannot find the models for the combination of the blockstate variables. I have the following working json /resources/assets/blockstates/block_magicleaves.json { "comment":"This references the models/block/model_name(without json extension) for the rendering", "variants": { "check_decay=true,decayable=true,type=therawoodleaveslight,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleaveslight"}, "check_decay=true,decayable=false,type=therawoodleaveslight,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleaveslight"}, "check_decay=false,decayable=false,type=therawoodleaveslight,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleaveslight"}, "check_decay=false,decayable=true,type=therawoodleaveslight,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleaveslight"}, "check_decay=true,decayable=true,type=therawoodleaves,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleaves"}, "check_decay=true,decayable=false,type=therawoodleaves,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleaves"}, "check_decay=false,decayable=false,type=therawoodleaves,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleaves"}, "check_decay=false,decayable=true,type=therawoodleaves,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleaves"}, "check_decay=true,decayable=true,type=therawoodleavesshaded,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleavesshaded"}, "check_decay=true,decayable=false,type=therawoodleavesshaded,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleavesshaded"}, "check_decay=false,decayable=false,type=therawoodleavesshaded,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleavesshaded"}, "check_decay=false,decayable=true,type=therawoodleavesshaded,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleavesshaded"}, "check_decay=true,decayable=true,type=therawoodleavesshaded3,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleavesshaded3"}, "check_decay=true,decayable=false,type=therawoodleavesshaded3,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleavesshaded3"}, "check_decay=false,decayable=false,type=therawoodleavesshaded3,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleavesshaded3"}, "check_decay=false,decayable=true,type=therawoodleavesshaded3,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleavesshaded3"}, "check_decay=true,decayable=true,type=therawoodleavesshaded4,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleavesshaded4"}, "check_decay=true,decayable=false,type=therawoodleavesshaded4,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleavesshaded4"}, "check_decay=false,decayable=false,type=therawoodleavesshaded4,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleavesshaded4"}, "check_decay=false,decayable=true,type=therawoodleavesshaded4,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleavesshaded4"}, "check_decay=true,decayable=true,type=therawoodleavesshaded5,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleavesshaded5"}, "check_decay=true,decayable=false,type=therawoodleavesshaded5,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleavesshaded5"}, "check_decay=false,decayable=false,type=therawoodleavesshaded5,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleavesshaded5"}, "check_decay=false,decayable=true,type=therawoodleavesshaded5,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleavesshaded5"}, "check_decay=true,decayable=true,type=therawoodleavesshaded6,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleavesshaded6"}, "check_decay=true,decayable=false,type=therawoodleavesshaded6,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleavesshaded6"}, "check_decay=false,decayable=false,type=therawoodleavesshaded6,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleavesshaded6"}, "check_decay=false,decayable=true,type=therawoodleavesshaded6,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleavesshaded6"}, "check_decay=true,decayable=true,type=therawoodleavesshaded7,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleavesshaded7"}, "check_decay=true,decayable=false,type=therawoodleavesshaded7,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleavesshaded7"}, "check_decay=false,decayable=false,type=therawoodleavesshaded7,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleavesshaded7"}, "check_decay=false,decayable=true,type=therawoodleavesshaded7,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleavesshaded7"}, "check_decay=true,decayable=true,type=therawoodleavesshaded8,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleavesshaded8"}, "check_decay=true,decayable=false,type=therawoodleavesshaded8,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleavesshaded8"}, "check_decay=false,decayable=false,type=therawoodleavesshaded8,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleavesshaded8"}, "check_decay=false,decayable=true,type=therawoodleavesshaded8,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleavesshaded8"}, "check_decay=true,decayable=true,type=therawoodleavesshaded9,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleavesshaded9"}, "check_decay=true,decayable=false,type=therawoodleavesshaded9,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleavesshaded9"}, "check_decay=false,decayable=false,type=therawoodleavesshaded9,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleavesshaded9"}, "check_decay=false,decayable=true,type=therawoodleavesshaded9,variant=therawoodlog": {"model":"magiccookies:magicleaves/therawoodleavesshaded9"} } } As you can see this is quite a nice repetition of code. The ONLY discerning fact in this json is the type variable, which dictates which leaves model gets loaded. { "forge_marker":1, "comment":"This references the models/block/model_name(without json extension) for the rendering", "variants": { "type" : { "therawoodleaves":{"model":"magiccookies:magicleaves/therawoodleaves"}, "therawoodleaveslight":{"model":"magiccookies:magicleaves/therawoodleaveslight"}, .... etc... } } } im getting the following messages: [15:11:02] [Client thread/ERROR] [FML/]: Model definition for location magiccookies:block_magicleaves#check_decay=true,decayable=false,type=therawoodleaves,variant=therawoodlog not found [15:11:02] [Client thread/ERROR] [FML/]: Model definition for location magiccookies:block_magicleaves#check_decay=true,decayable=false,type=therawoodleavesshaded6,variant=therawoodlog not found [15:11:02] [Client thread/ERROR] [FML/]: Model definition for location magiccookies:block_magicleaves#check_decay=false,decayable=true,type=therawoodleaves,variant=therawoodlog not found [15:11:02] [Client thread/ERROR] [FML/]: Model definition for location magiccookies:block_magicleaves#check_decay=true,decayable=true,type=therawoodleavesshaded7,variant=therawoodlog not found [15:11:02] [Client thread/ERROR] [FML/]: Suppressed additional 40 model loading errors for domain magiccookies I'd like to learn how to use the forge marker properly in forge 1.8.9
  3. In this tutorial i'm putting what I figured out what worked for me to get metadata item textures working again in an easy maintainable way for me. It involves a couple of classes and an interface to be set up, but it's pretty simple. In this tutorial I will however only show the neccesary code, not fully functional items etc... because I can't be bothered to strip all the support code form the one item I have. First, we make a class to register all our items for rendering in. There are probaly better ways to do this, but this is what I used during my experimentations. Feel free to implement your own way, with or without singleton, static, dynamic, lists, whatever you fancy :-) public class ItemRenderRegister { /** * @var render Singleton of the render register that we use **/ private static ItemRenderRegister render; private ItemRenderRegister(){} /** * Get the instance of the ItemRenderRegister * @return ItemRenderRegister instance */ public static ItemRenderRegister instance() { if(ItemRenderRegister.render == null) { ItemRenderRegister.render = new ItemRenderRegister(); } return render; } /** * The method where we put all our items. You could possibly use * a list method here too where you get all your mod items from a list * Feel ree to use whatever method you choose, hardcoded, list, magic */ public static void registerItemRenderer() { // save the minor overhead of calling the function ItemRenderRegister inst = instance(); // Register our item, let the rest do magic inst.reg(ItemLibrary.stripper); } /** * if the item is an instance of IItemVariantDetails * then let the item itself handle the registration of details * This is to keep code where it's logical(imho). */ public void reg(Item item) { // self defining item? Let it do it's thing if(item instanceof IItemVariantDetails) { ((IItemVariantDetails)item).registerItemVariants(this); } else { // Assume there is only one item with meta data 0 reg(item,0); } } /** * Register item, look for JSON file based on registry name. * @param item The item to register * @param metadata The meta data to register it with */ public void reg(Item item, int metadata) { reg(item,metadata,item.getRegistryName()); } /** * Register all our textures so forge knows them * @param item The item to register * @param metadata The meta data the texture applies to. * @param file The name of the JSON file in "assets/MODID.toLowerCase()/models/items" without the .json extension */ public void reg(Item item, int metadata, String file) { //Get our resource location up and running ModelResourceLocation location = new ModelResourceLocation( MagicCookies.MODID.toLowerCase() + ":" + file, "inventory" ); // register the different variants(if any) ModelLoader.setCustomModelResourceLocation(item, metadata, location); } } Then we also need the interface we check the instance of above here public interface IItemVariantDetails { /**<pre> * Method to register item variants * Usage to register items: * <b>register.reg(this , metadata , String JSON_filename );</b> * <i>register.reg(this , 4 , "my_json_filename_without_extension" );</i> * for all different variants</PRE> */ public void registerItemVariants(ItemRenderRegister register); } public class StructureGenStripper extends Item implements IItemVariantDetails { public StructureGenStripper( String unLocalizedName ) { super(); this.setUnlocalizedName( unLocalizedName ); this.setCreativeTab( ModHooks.creativeTabMagicCookies ); this.setMaxStackSize( 1 ); this.setMaxDamage( 0 ); this.setHasSubtypes( true ); } .... // code to do magic for your item, do as you please @Override public void registerItemVariants(ItemRenderRegister register) { register.reg( this , 0 , "itemStripper" ); register.reg( this , 1 , "itemStripperair" ); register.reg( this , 2 , "itemStripperSolid" ); register.reg( this , 3 , "itemStripperPlacer" ); register.reg( this , 4 , "itemStripperAssorted" ); register.reg( this , 5 , "itemStripperUndo" ); } Then in our client proxy we can call our rendere instantiation code, because graphics on the server side serve no purpose public class ClientProxy extends CommonProxy { public void registerRenderers() { ItemRenderRegister.registerItemRenderer(); } } And we can call the renderers in our main mod class in the pre init. @EventHandler public void preInit( FMLPreInitializationEvent event ) { this.proxy.registerRenderers(); } So to recap. when all this code is all settled nicely in your mod, you only have to add the interface to your item, have eclipse add the method to your item and add your item to your ItemRenderRegister in the manner of your choosing and you're all set to go for your items and different icons. How to set up icon jsons i'll leave up to you. That's a whole other can of worms. Just give them the exact same filename you define in the strings(case senstive) If someone has a better way to do this, or more elegant, or if there's a path i'm unaware of, please, i wnat to know :-) This is just what I cobbled together in a night to make my life easier, but if there are better ways, or things i've overlooked, I do love knowing about it :-) - Tsch
  4. for those wondering how, you need to invoke func_143026_a of MapGenStructure in your structure gen class when you give back the start piece in the protected StructureStart getStructureStart(int chunkX, int chunkZ) method.
  5. I have a structure generation in my mod public class MapGenEntropyTemple extends MapGenStructure { } and it works beautifully, it generates the entropy temple as it should. There is only one caveat, the MapGenStructureData doesn't get saved the moment minecraft closes and then gets started again. Al the locations I could poll(very accurately, I have my boundingboxes fit nice and tight around my sections) StuffLoader.worldGenerator.genEntropyTemple.hasStructureAt(player.worldObj,(int)player.posX, (int)player.posY, (int)player.posZ) suddenly return false in the new minecraft session. So they return true in the minecraft play session that generated the entropy temple. But if the world is reloaded in a freshly (rebooted) minecraft, the lists are empty. I kinda need to know what the trigger is so I can make sure minecraft actually saves the locations of the gen structure. This also is the cause why sometimes only half my entropy temples render, because it doesn't save its progress as it should to file. So I might be missing something, a trigger, a value, and i'm hoping someone here knows what to do. I have tried to trace it, and I found this in MapGenStructure this.field_143029_e = (MapGenStructureData)p_143027_1_.perWorldStorage.loadData(MapGenStructureData.class, this.func_143025_a()); if (this.field_143029_e == null) { this.field_143029_e = new MapGenStructureData(this.func_143025_a()); p_143027_1_.perWorldStorage.setData(this.func_143025_a(), this.field_143029_e); } and it seems to save and set everything, register it to the perWorldstorage, so it should be saved on world nbt save run. since i'm polling on player tick where the player is. Yet when I poll the file directly after a minecraft restart, I get x = (MapGenStructureData)player.worldObj.perWorldStorage.loadData(MapGenStructureData.class, "EntropyTemple"); NBTTagCompound y = new NBTTagCompound(); x.writeToNBT(y); MagicCookie.log.warn(y.toString()); {Features:{},} So, anyone know which methond/function I should trigger in MapGenStructure to make sure it saves to disk and gets read to disk? Any event handlers I should hook into for this? Of course I can make my own save handlers for my own purposes, but i'd rather have it that this works so minecraft can keep my rather sizeable structures in account when placing nether fortresses or other generated structures. It does that now in the same session, but not if the minecraft server or single player client gets restarted.
  6. I wish I had crash logs, then it would have been easy to pinpoint. But what we got were only the crashes that the service just stopped because the OS killed it/detected it dying. Thanks for the modifications though :-)
  7. Okay, so he started bragging about how smart he is and bla bla but he dropped his attack vector. He's requesting the motd multiple times which causes the server to crash because of all the json that gets compiled to answer the request. Now my question is basically this: Is there a way in forge that I can catch when S00PacketServerInfo is sent and to which ip? Then I can log that so IPTables can block it. If I should write a coremod for this, which would be the best point to hook it in so I can get the IP? Anyone have experience with this?
  8. Hmmh, then he must be using a different weakness. I so thought he used this one... Clearly he's not whitelisted. I'm kinda stuck atm with coreprotect and cauldron. so im still chugging along with forge 1231. I am writing my own anti grief/logging mod as we speak, and it would be relatively simple to turn it into a 1.7.10 mod so we can finally update forge. I was just hoping someone would have made a coremod to fix this.
  9. Heya, **Edited 03/07/2015 with relevant information. I found out his attack vector** I'm having issues with a hacker who crashes my 1.7.10 server by repeatedly requesting the MOTD by which the memory overflows on the server because of the json that gets compiled over and over(playercount and such) He crashes my server multiple times a day because he doesn't get whitelisted. So, basicaly I want to write/use a mod that logs how often the MOTD gets requested. I know I have to use the trail that sends s00PacketServerInfo, but what i'm wondering is how to get the IP of the user requestion so I can log it and hand it over to IPtables if it reaches a treshold. Kind regards, Tschallacka
  10. I am suspecting you added a deobfuscated(development) jar to your mods folder. Thisjar uses deobfuscated methods which works great in eclipse but doesnt work in a "live" enviroment because minecraft uses obfuscated code. Download the obfuscated. Jars and try again.
  11. Minecraftforum post: http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-mods/wip-mods/2423847-who-took-my-cookies-a-forge-blocklogging-mod This is a blocklogging mod i'm developping for forge clients/servers. It currently logs only placed, broken, exploded and altered blocks. Current features consists of: Logging broken blocks with nbtdata Logging exploded blocks with nbtdata and suspect list Logging placed blocks Logging updated blocks(dirt turning into grass etc...) Rollback of removed/broken blocks on a per block basis Ops only/creative world usuable only Serverside only mod. No clientside mod required. Download the beta https://drive.google.com/file/d/0ByZ5fzt_E1VWU1ZSQVluNXRsM0k/view?usp=sharing For single player worlds you need to keep in mind that it only uses ONE database per minecraft game/computer(I havent tested with different profile folders yet... maybe that way you can have multiple single player databases) Please try it out and test it extensively and report back to me if you find serious issues and please give me idea's for features you would like to see added(entity tracking, inventory tracking, radius rollback, player specific rollback, will be added already. special mod compatibility that are know to cause trouble with logging plugins?) Things i'm interested in: When execution time is above 50ms & what your server/computer is doing at that time(seriously, all queries should complete within 0-5ms) If you encounter really slow queries i'd like a copy of your database along with your notition of it. Crashes. Give me crash reports. thank you. Mod incompatiblity issues... Crash reports/client-latest the whole shebang. [*]Idea's, what would you like to see added as a feature To use it you basically only need to know one command: /whotookmycookies inspect (possible aliases are /co inspect and /wtmc inspect) Then you can access the logs by placing blocks at the location you wish to inspect(the breaking blocks to inspect part doesnt work yet) To disable type the above command again. The rest of the commands are accessible by clicking on the relevant buttons in the chattext. See the below screenshots for an impression how the beta looks and behaves and where the extra hooks in the chattext are you can click on.
  12. How would these blocks detect the markdirty call then?
  13. Is it possible that the entity code is in a different thread? That way it could be possible they are asking the same random state at the same moment which would result in the same nextInt to be returned in the randomness step. how rand works is Rand(seed) will always return the same next values in order Nextint 2 Nextint 4 Nextint 7 Is it possible that the stepvalue gets reset in the world object or that it gets cloned for the tick event? As not to mess up worldgen? That would also explain the same values because step will always be the same. Future steps will be different because they might happen in seperate ticks. There are multiple possibilities why the random is the same.
  14. The world random object has a seed. Which makes it predictable in behaviour. Thats why maps with a seed spawn the same stuff on different computers. If you want more randomness construct your own Random object and use that. That way it operates without the seed constraints.
  15. I was wondering how i can get an event when a tileentity calls markdirty() I want to monitor changes in certain tileentities of other mods and perform an action corresponding to that. Does markDirty() cause a bud update or is there an event fired?
  16. o_O You render a big ass image of 600x600 and then you cut it up into a smaller image? Why not render it into a smaller image? saves spaces on bandwidth to graphics card. Please post of a screenshot of what you have... and what you want it to look because I have the feeling I don't understand what you want
  17. 600x600? Thats huge. Thats bigger than default texturemap... I'd suggest you calculate the image once per tick. Not every frame and reuse that image in rendering instead of recalculating it every frame. The image itself takes up roughly 1.3 mb in ram. Not to mention variables used in the calculation process. If you run this every frame your heap space gets full really fast. By calculation once per tick or several ticks you give the garbage collector time to catch up.
  18. You need to make a new pane class for yourself, but you also need to copy the corresponding renderer and put it in a blockrenderee of your own( just take the render id and select the corresponding render code from the if statements in the vanilla blockrenderer) Then modify it. If you extend blockpane on the block you also allow other mods to connect to it which would do it this way.
  19. Its really simple. First of all. Rule number 1 all non gui code must happen on server. Currently you are running code simultanouslyserverside and clientside. Anything that has to do witch changing blockstates has to be serverside. Now in your example im going to presume your fire will always be on another block. This where you use the PlayerInteractEvent to detect if your fireblock is a possible target Some pseudocode(im on mobile) @Eventhandler Public void userclick(PlayerInteractEvent event) { If(!event.world.isRemote) { If(event.action == Action.LEFT_CLICK) { if(event.world.getBlockState(event.pos.offset(event.face)).getBlock() == MyCustomChickenFire) { Event.world.setBlockToAir(event.world.getBlockState(event.pos.offset(event.face)) ); //playsound hiss //spawn smoke fx via networkpacket to client to tell it to spawn the fx } } } }
  20. Its all cool then and apology accepted. Yea. I meant the PlayerInteractEvent. Im doing this all from mobile :-) If you have left click event on the block where the fire is you can use event.world.getBlockState(event.pos.offset(event.face)) to get the block you want to check if its fire. You might want to check first if the click was a left click and the item held is an "approved" item to extinguish the fire(bare hand, non weapon item, chicken feathers) You can then use the face even to decide to extinguish only one flame or all flames.(i would choose the one flame on the hit side but thats just me) When you update the blockstate it should automatically push to the client. Maybe worth to check that you are running the changing blockstate code only serverside(the firespread)
  21. Well i read your topic. You have a custom fire and you try to extinguish it by hitting it. This can all be accomplished server side by the iteminteract event. Then when you extinguish it you wish to kill it without breaking the block behind it. This is a simple matter of setblocktoair where the fire is at where it was hit. If you are worrield about the blockpos being 0 0 0 with click air you can still calculate where was looked from the entityplayer. Heck. If you wish to extinguish one flame instead of multiple in the block you can use the face hit and intrepolate the flame to extinguish and update the blockstate. Id add a cooldown for that side so it cant catch fire quickly again. This is all serverside. Then the server sends to clients the instruction to spawn a few fx smoke particles and play the sound at clients. Seriously. I read. I just thaught id respond cause i tackled a similar problem today. Just trying to help. But i guess this forum doesnt need help with such hostile atmosphere. Just to continue the atmosphere: this is a dead simple problem.
  22. UhM... Dont do the mouse hackery... Just send a datapacket to the client to spawn smoke particles or whatever you want for fx And do a playsound. That way not only you get the correct behavour but players around you too. Pet peeve of mine is thaumcraft warded particles only showing for player hitting the block. Let the server decide which particles where and how, the update all players in vicinity with the data
  23. Yea. Im using the phase.END to clear the during tick detected itemclock positions. I build those up so i can detect armourstands,lava and water being placed. But no use to leave those locations lingering around when the tick has ended. Btw, im very pleased with the blockpos offset calculator. Makes life so much easier.
  24. [21:10:09] [server thread/WARN] [WHOTOOKMYCOOKIE]: event.pos = BlockPos{x=0, y=0, z=0} [21:10:09] [server thread/WARN] [WHOTOOKMYCOOKIE]: event.action RIGHT_CLICK_AIR [21:10:09] [server thread/WARN] [WHOTOOKMYCOOKIE]: event.entity EntityPlayerMP['Player810'/206, l='New World', x=3,88, y=44,00, z=9,79] [21:10:09] [server thread/WARN] [WHOTOOKMYCOOKIE]: event.entityLiving EntityPlayerMP['Player810'/206, l='New World', x=3,88, y=44,00, z=9,79] [21:10:09] [server thread/WARN] [WHOTOOKMYCOOKIE]: event.entityPlayer EntityPlayerMP['Player810'/206, l='New World', x=3,88, y=44,00, z=9,79] [21:10:09] [server thread/WARN] [WHOTOOKMYCOOKIE]: event.face null [21:10:09] [server thread/WARN] [WHOTOOKMYCOOKIE]: event.useBlock DENY [21:10:09] [server thread/WARN] [WHOTOOKMYCOOKIE]: event.useItem DEFAULT [21:10:09] [server thread/WARN] [WHOTOOKMYCOOKIE]: event.world net.minecraft.world.WorldServerMulti@4b95ed [21:10:09] [server thread/WARN] [WHOTOOKMYCOOKIE]: event.getPhase() NORMAL [21:10:09] [server thread/WARN] [WHOTOOKMYCOOKIE]: event.getResult() DEFAULT [21:10:09] [server thread/WARN] [WHOTOOKMYCOOKIE]: event.hasResult() false Okay... so right click air doesnt give position? I guess you could get the position from the player location in that case. So basically right click air always fires even when the event that initialises this was a lava bucket placing lava? Is that because you "cross" through air on the way to the block? I kinda get the logic now behind this "double" event fire. Although i'd expect the air event to fire before the item used on a block event. but I guess thats a matter of opinion.
×
×
  • Create New...

Important Information

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