Z0rdak / Yet-Another-World-Protector

Yet Another World Protector is a server-side protection mod which allows you to protect your creations against various different events/actions of players, mobs and the environment. It was inspired by the forge mod WorldProtector and the WorldGuard plugin.
https://www.curseforge.com/minecraft/mc-mods/yawp
GNU Affero General Public License v3.0
19 stars 8 forks source link

Is Frost Walker being cancelled correctly? #85

Closed harlanw closed 1 year ago

harlanw commented 1 year ago

Hi, I had an issue which you can read about here: https://github.com/Caltinor/Project-MMO-2.0/issues/294

I was wondering if you could show me where in your codebase your frost walker logic is actually handled? I am probably missing something fundamentally about Forge, but I couldn't find where, for example, you check to see if frost blocks are being spawned or something (rough idea). I know there is the mixin but I think that is only part of the picture.

Thanks!

Z0rdak commented 1 year ago

For reference, posted in Calintor/Project-MMO-2.0#294

Hey there @Caltinor and @harlanw Z0rdak here, the dev of YAWP.

  • [3] Agreed.
  • [5] Agreed.

The mixin is hooking after the forge event. It does prevent the block from being placed (given that the flag is set), but >does not mark the event as canceled, thus having not the desired effect in your scenario.

I implemented this particular flag first in the Fabric port. Since there is no event bus system in Fabric I used a mixin for >this. And I use the same mixin in Forge and only NOW have I realized that forge has put a hook for place block there as >well.

Long story short: I'll remove the mixin for this flag in the Forge port and replace it with the Forge event. This way it should be compatible.

Best regards Z0rdak

harlanw commented 1 year ago

Thanks @Z0rdak for providing that context! As a matter of personal interest, could you point me to wear your code actually sets the flag for this? I found some likely spots but couldn't fully track it down when I peeked at it earlier.

Great mod by the way. I just started using Forge and was surprised there wasn't a WorldGuard port.

Region triggers for entering/leaving a region (for displaying messages, executing commands, etc)*

Especially looking forward to this bullet point

Z0rdak commented 1 year ago

The flag is set within the RegionCommands, saved and checked later.

Is this what you were looking for?

Best regards

harlanw commented 1 year ago

Okay, typing out a reply I think I realized what is happening. Your mixin hooks into onEntityMove, and the only time the vanilla client calls "setBlockAndUpdate" in this context is from frost walker. Is that correct?

Z0rdak commented 1 year ago

Correct. Thats exactly what I was trying to explain here.

The mixin hooks into the setBlockAndUpdate at the end of the function onEntityMoved in FrostWalkerEnchantment.java vanilla code below. The forge event is in the condition one line before this:

 public static void onEntityMoved(LivingEntity p_45019_, Level p_45020_, BlockPos p_45021_, int p_45022_) {
      if (p_45019_.isOnGround()) {
         BlockState blockstate = Blocks.FROSTED_ICE.defaultBlockState();
         float f = (float)Math.min(16, 2 + p_45022_);
         BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos();

         for(BlockPos blockpos : BlockPos.betweenClosed(p_45021_.offset((double)(-f), -1.0D, (double)(-f)), p_45021_.offset((double)f, -1.0D, (double)f))) {
            if (blockpos.closerToCenterThan(p_45019_.position(), (double)f)) {
               blockpos$mutableblockpos.set(blockpos.getX(), blockpos.getY() + 1, blockpos.getZ());
               BlockState blockstate1 = p_45020_.getBlockState(blockpos$mutableblockpos);
               if (blockstate1.isAir()) {
                  BlockState blockstate2 = p_45020_.getBlockState(blockpos);
                  boolean isFull = blockstate2.getBlock() == Blocks.WATER && blockstate2.getValue(LiquidBlock.LEVEL) == 0; //TODO: Forge, modded waters?
                  if (blockstate2.getMaterial() == Material.WATER && isFull && blockstate.canSurvive(p_45020_, blockpos) 
                       && p_45020_.isUnobstructed(blockstate, blockpos, CollisionContext.empty()) 
                       && !net.minecraftforge.event.ForgeEventFactory.onBlockPlace(p_45019_, net.minecraftforge.common.util.BlockSnapshot.create(p_45020_.dimension(), p_45020_, blockpos), net.minecraft.core.Direction.UP)) {
                     p_45020_.setBlockAndUpdate(blockpos, blockstate);
                     p_45020_.scheduleTick(blockpos, Blocks.FROSTED_ICE, Mth.nextInt(p_45019_.getRandom(), 60, 120));
                  }
               }
            }
         }

      }
   }

could you point me to wear your code actually sets the flag for this?

I was a little confused why you would want to know where I set the flag if you were looking for this. Anyway, hope its clarified :)

Z0rdak commented 1 year ago

Will be resolved in 0.0.2.9-beta1.