FallingTree

FallingTree

28M Downloads

Shift Down compat w/ ProjectMMO

qwitwa opened this issue ยท 6 comments

commented

Describe the bug
Similar to #11, Project MMO does not give experience for woodcutting when blocks are cut with the Shift Down setting on Falling Tree. Loris in the PMMO discord claimed this was because the ShiftDownTreeBreakingHandler sets the event to cancelled.

To Reproduce
Steps to reproduce the behavior:

  1. Start a game with PMMO and Falling Tree with the Shift Down setting on
  2. Break a tree wood block with an axe
  3. Observe that no woodcutting XP is given

Infos:

  • Minecraft version: 1.6.15
  • Mod version: Falling Tree 2.11.3, Project MMO 3.57
  • Forge version: 36.1.16
commented

I'm aware of this but won't be able to do too much about this.

The issue is like "Loris" told you. In the case of shift down FallingTree marks the breaking event as cancelled (so like if nothing happened). That is because it isn't breaking the log that you're targeting but instead breaks the one the furthest away.

What happens under the hood is:

  • Forge tells that a block has been broken (event)
  • If this is a tree and we're in shift down mode, then:
    • FT breaks the log the furthest away with your tool
    • FT cancels the event so the original block isn't broken

Sadly I don't really know how to get to the same end result without having to cancel the event. If people have ideas then I'm open to it.

I thought of letting the event pass through (not cancelling it), making it so that the targeted block is actually destroyed and then "move" the furthest block to the broken position. But that seems even worse to me and lead to more incompatibilities with mods. Plus that wouldn't be as smooth as you just hold your click to break logs.

What seems the best to me would be to fix this issue in the case of project MMO by having an API provided by it. Like an interface in which I can hook into at runtime (and not with a hard dependency forcing all the users of FT to have PMMO) and where I can tell "Hey, the dude broke this block". And then it can do its logic of whatever it does but without relying on the event.
That'd require quite some work on the side of PMMO though.

Well basically as it is it won't work and it's a "choice" because I have no other options. If some are available I'm willing to make the changes for it. Also regarding the interface thing, this could also be done the opposite way where I provide an API mods can hook into and get notified when a tree is broken (with infos like what size the tree is, if it was all chopped down or just one piece, ...).

commented

Or maybe more simple we could setup IMC in place between the two mods. Without requiring an interface as it'd be handled by forge.

commented

RakSrinaNa,

What you could do is post your own event when you break the distant log. In this way you still cancel the breaking of the targeted log, but the other log triggers an event that other mods can detect.

for example on line 32 of ShiftDownTreeBreakingHandler you could insert

int exp = net.minecraftforge.common.ForgeHooks.onBlockBreakEvent(world, gameModeForPlayer, player, pos);
if (exp == -1) {
    return false;
}

This has the added advantage of protecting tree branches that might cross over into protected claims, thought I know that wasn't the OPs original scenario.

commented

Yeah I like the idea of firing an event. It's simple and doesn't require any additional things from other mods. It simple "patches" the fact I break another block and notify it to others.

Though that means I have to fire the event before actually breaking the log (as we send just the world & the position), which means I'll also receive the event myself which will trigger a tree detection and loop the whole thing over and over again.

What I could do though is fire a custom event that extends the BlockBreakEvent. This way:

  • Other mods can intercept the event as a block break event
    • If needed they can cancel the event (like parcel protection mods)
  • Forge doesn't insert its logic into it
  • I can internally check that the event isn't my custom type and avoid recursive calls

I did these changes with a custom event. Can try with this build

  • @qwitwa Does that fixes the issue with PMMO ?
  • @Caltinor I don't really know how to try the cancellation of the event. As you mentioned this point maybe you play with mods that do parcel protection ?

If this work well I can extend this notion of event to also support the instantaneous mode. This would potentially avoid removing blocks from a protected parcel, and also PMMO would (I guess) could every block of the tree as being broken instead of just one. I don't know if it's really "fair" as you actually cut just one, but at the same time the tool did take the amount of damage of the whole tree...

commented

Yeah, this works great, thanks.

commented

@RakSrinaNa I develop mods that do parcel protection. the cancellation is done on the protection mod end. All you need to check is whether the event is cancelled or not. So you create an instance of your event, post it to the event bus, then on the next line, you can check if (event.isCanceled()) dontDoTheBehavior();

the example from above is a simple implementation of this, but if you don't want all the baggage from the onBlockBreakEvent you could just replicate that method minus the unnecessary stuff.