Jump to content

Recommended Posts

Posted (edited)

So I wrote a mod to make paths as you walk. (It's already up here.) It does what it's supposed to, which is amazing.

Except that when you quit, all your paths are gone when you start the world again.

 

I'm guessing I have to tell the program to commit the changes to the world somewhere... and I'm a n00b so I have no idea where/how to do that. Something about client/common classes and stuff probably...... Anyone have a good tutorial that explains how and why?

 

Current Code:

Spoiler

@EventBusSubscriber

public class MakePath {

 

 

@SubscribeEvent

public static void makePath(LivingUpdateEvent event) {

if (event.getEntity() !=null && event.getEntity() instanceof EntityPlayer) {

Entity player = event.getEntity();

BlockPos entityLocation = new BlockPos(player.posX, player.posY + player.getYOffset(), player.posZ);

World world = player.getEntityWorld();

IBlockState state = world.getBlockState(entityLocation);

Block block = state.getBlock();

 

double random = Math.random() * 100 + 1;

 

if (player.motionX > 0 || player.motionY > 0 || player.motionZ > 0)

{

if (block instanceof BlockGrass)

{

if (random < 25) {

        world.setBlockState(entityLocation, Blocks.DIRT.getDefaultState());

}

}

 

}

}

 

 

Edited by T.S.White
Posted
1 hour ago, T.S.White said:

world.setBlockState(entityLocation, Blocks.DIRT.getDefaultState());

That is your "commit the changes to the world somewhere" line. You're done.

The only thing wrong with your code is that instead of using LivingUpdateEvent you should use PlayerUpdateEvent. Also, those updates have Phases, you should check for one of them (START or END).  You should probably also do an if(!world.isRemote) check, just to insure you're on the server.

 

Have you tried the debugger?

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted (edited)
57 minutes ago, Draco18s said:

Have you tried the debugger?

EDIT: nm. I know what that is. XP

Spoiler

"Debugger?" she says with wide eyes, "that would be helpful!" /derp

How do I find and use this magic?

 

 

Since it is apparently not my first guess and I am already (apparently) updating the world, I have to ask about the theory that seemed fundamentally wrong:

BlockStates are ALL the block info, right? So I'm updating the actual block and all its state info. It couldn't be tripping over something about updating the State and not the Block, right?

 

Thanks for the tip about PlayerUpdateEvent. That makes way more sense since it's currently just the player doing this thing. And the !world.isRemote check too.

 

Phases when the UpdateEvent gets called? Like, you can make the ForgeEvent go before or after the original minecraft code that forge is hijacking? If I'm understanding right, that could be incredibly useful.

Edited by T.S.White
Posted

Draco18s, the reason he's using the living update event is that he actually wants many types of entities to do the same and just started with the player.

 

Yes, the phases allow you to get some control of your code versus the original. Usually the START is cancellable to allow you to fully replace the vanilla code whereas the END would simply augment the vanilla code.

 

The debugger is a feature of your IDE (probably Eclipse but maybe you're using IDEA or something else) that allows you to inspect code execution by methods such as setting breakpoints which will stop execution and let you see the value of various fields at that point. There are plenty of tutorials on such things. It is very useful but I often prefer using console statements instead because I like to watch behavior in real-time -- like actually play the game while watching some value change. But debugger is something you should absolutely become comfortable with.

 

Now to your actual problem about the change not being saved it seems a bit odd. As Draco18s mentioned, the set block state method should be sufficient. 

 

However, I think it is a problem with the sides. The tick event actually gets called four times per tick -- once for each phase and then per side. I have the feeling that your code is only true on the client side. This is because I think player motion is controlled primarily on the client side (still enforced on the server to prevent cheating) to avoid glitchiness waiting for server synchronization.

 

So to debug this I would set a breakpoint on the if statement and check the value of the motion fields and such. You may find that motion is 0 on server and so never sets the block. But the server is side where saves happen.

 

You could also prove this theory by deleting the check for motion and simply always changing the block under the entity. If you  find that that saves properly, it implies that the check for motion was the issue.

 

If that is indeed the problem, you could create a server-side check for "motion" by simply subtracting previous positions from current positions (and be sure to take the absolute value).

 

By the way, you have a bug in your code because motion can be negative. So your if statement would also not trigger if you walked in certain direction.

 

 

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Posted
5 minutes ago, jabelar said:

Draco18s, the reason he's using the living update event is that he actually wants many types of entities to do the same and just started with the player.

True, but it's not super critical to have All entities do this. Priority is to get the player working.

 

Quote

By the way, you have a bug in your code because motion can be negative. So your if statement would also not trigger if you walked in certain direction.

I was laughing just before you posted because of this. Already fixed with abs.

 

 

 

Quote

You could also prove this theory by deleting the check for motion and simply always changing the block under the entity. If you  find that that saves properly, it implies that the check for motion was the issue.

Oooh. That was interesting. This doesn't solve the problem if I use PlayerEvent, but it does fix it if I use LivingUpdateEvent.

Which tells us several things: 1. It is indeed a client vs. server issue, and 2. PlayerEvent = Client Side, LivingUpdateEvent = Server Side, and Player-Specific Motion (the motionXYZ is player specific) = Client Side.

 

Aaaaand that means I need to figure out how to tell the server that the client changed the block and it should do the same.

I set up client and common proxies. And the ClientProxy extends the CommonProxy, and something goes in one or both of those. Right? I'm pretty sure that's the bit that's missing.

(I understand the Client/Server/Common concepts pretty well. It's using them that's the issue.)

Posted

There are server side player events, but the player's motion is always 0 (because the client is the authority, the server ends up just teleporting the player to where the client says the player should be).

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted (edited)

I think I'm getting this better now. Since I'm calling the "doSomething" code inside of a ClientEvent, it has Nothing to do with the server. So I'm going to have to run the If on the client side and return a boolean, which I can then use on the server side to setBlockState. I think. Does that make any kind of sense?

 

(I really wish I knew Java better. Most of my experience is with Agent Based Modeling, and everything in Java, and minecraft, seems SOOO backwards and top-down compared to the way I would do it with agents.)

Edited by T.S.White
Posted
11 minutes ago, T.S.White said:

So I'm going to have to run the If on the client side and return a boolean, which I can then use on the server side to setBlockState. I think. Does that make any kind of sense?

Doing that requires packets.

But you should not need packets for this. There are already events for the player that run server side.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted
1 minute ago, Draco18s said:

Doing that requires packets.

But you should not need packets for this. There are already events for the player that run server side.

Gotcha. Let's make it easier then and not do the crazy side-switcheroo dance.

I can also (probably) fix it by using a different way to check if the entity is moving (which also means I can get other entities to do this! yay!), but I need to get my priorities straight. Because all the other ways I came up with to figure out if something is moving got changed in methods that got called before mine. That's why I was so excited to hear that you could make them execute first... /ramble
 

Quote

Also, those updates have Phases, you should check for one of them (START or END).

So, I have a LivingUpdateEvent, and I need to attach the thing that says "go first".  Which is START vs END? Is it also the same as this? And how does that fit into the code?

Posted
7 minutes ago, T.S.White said:

Which is START vs END? Is it also the same as this? And how does that fit into the code?

No, priority is what order event handlers (mod code) are executed. Without specifying (or specifying the same priority as another mod) means they go in the same order that the mods were loaded.

 

Phase is whether the event is fired before the vanilla code executes or after the vanilla code executes.

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Posted
21 minutes ago, Draco18s said:

No, priority is what order event handlers (mod code) are executed. Without specifying (or specifying the same priority as another mod) means they go in the same order that the mods were loaded.

 

Phase is whether the event is fired before the vanilla code executes or after the vanilla code executes.

 

huh. I was messing with it and changed it to

@SubscribeEvent(priority=EventPriority.HIGHEST)

 which completely fixed the problem...

 

Probably Wrong: I'm guessing that the priority treats Minecraft Itself as it would a Mod, so if it fires at HIGHEST priority Minecraft fires somewhere after and does something that updates the blocks on the server.

 

 

Thanks for all your help, btw. Every time you answer a question I seem to learn about something I hadn't even considered. 

Posted
Quote

Probably Wrong: I'm guessing that the priority treats Minecraft Itself as it would a Mod, so if it fires at HIGHEST priority Minecraft fires somewhere after and does something that updates the blocks on the server.

You're wrong. 

Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable.  If you think this is the case, JUST REPORT ME.  Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice.

 

Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked.

 

DO NOT PM ME WITH PROBLEMS. No help will be given.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

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