gnembon / fabric-carpet

Fabric Carpet
MIT License
1.65k stars 261 forks source link

persistentParrots = incompatibleParrots with Bole Handbook #1805

Open 800020h opened 10 months ago

800020h commented 10 months ago

versions:

observed behaviour:

when bole and carpet are both present and persistentParrots is true it works as expected when persistentParrots is false bole's fallDistanceToDropShoulderEntities config doesn't work

expected behaviour:

when persistentParrots is false bole's fallDistanceToDropShoulderEntities config would work

notes:

bole link:

https://modrinth.com/mod/bole

bole config used:

.minecraft/config/bole.json

{
  "shoulderCreatureHudPosition": "NONE",
  "notifyWhenLeashFallFromPlayer": false,
  "receiveWanderingTraderSpawnBroadcasts": false,
  "highlightEntitiesBlindnessTime": 40,
  "allowHotKeyToOpenBoleHandbookScreen": false,
  "blockAccidentalInjuryToPets": false,
  "petsCanTeleportToMoreBlocks": false,
  "fallDistanceToDropShoulderEntities": 3.0,
  "forbidToSetNetherPortalCooldownOfOtherPlayers": false,
  "broadcastWhenWanderingTraderSpawn": false,
  "bannedEntitySettings": []
}
800020h commented 10 months ago

log https://gist.github.com/800020h/b6b6ef35bcc1e6faff7e5bed3f7a67e4

xienaoban commented 10 months ago

The related raw logic is:

// mojang mapping: public void aiStep()
if (!this.level.isClientSide && (this.fallDistance > 0.5F || this.isInWater()) || this.abilities.flying || this.isSleeping() || this.isInPowderSnow) {
   this.removeEntitiesOnShoulder();
}

// or yarn mapping: public void tickMovement()
if (!this.world.isClient && (this.fallDistance > 0.5F || this.isTouchingWater()) || this.abilities.flying || this.isSleeping() || this.inPowderSnow) {
    this.dropShoulderEntities();
}

And in the mixin file src/main/java/xienaoban/minecraft/bole/mixin/MixinPlayerEntity.java of bole:

@Redirect(method = "tickMovement()V", at = @At(value = "FIELD", target = "Lnet/minecraft/entity/player/PlayerEntity;fallDistance:F", opcode = Opcodes.GETFIELD))
private float injected(PlayerEntity instance) {
    float time = Configs.getInstance().getFallDistanceToDropShoulderEntities();
    return instance.fallDistance / (Math.max(time, 0.001F) * 2);
}

I rewrote the logic of this.fallDistance > 0.5F.

But in the mixin file src/main/java/carpet/mixins/Player_parrotMixin.java of carpet:

@Inject(method = "aiStep", at = @At(value = "INVOKE", shift = At.Shift.AFTER, ordinal = 1,
        target = "Lnet/minecraft/world/entity/player/Player;playShoulderEntityAmbientSound(Lnet/minecraft/nbt/CompoundTag;)V"))
private void onTickMovement(CallbackInfo ci)
{
    boolean parrots_will_drop = !CarpetSettings.persistentParrots || this.abilities.invulnerable;
    // →→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→ the problem is here ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
    if (!this.level.isClientSide && ((parrots_will_drop && this.fallDistance > 0.5F) || this.isInWater() || this.abilities.flying || isSleeping()))
    {
        this.removeEntitiesOnShoulder();
    }
}

Carpet rewrote the whole logic, so my logic doesn't work anymore.

xienaoban commented 10 months ago

Maybe a better solution is to put the judgment parrots_will_drop into the if statement:

// ...
if (!this.level.isClientSide && (this.fallDistance > 0.5F || this.isInWater()) || this.abilities.flying || this.isSleeping() || this.isInPowderSnow) {
    // 👇inject something like the following:
    boolean parrots_will_drop = !CarpetSettings.persistentParrots || this.abilities.invulnerable;
    if (parrots_will_drop) {
        this.removeEntitiesOnShoulder();
    }
    // 👆end of injection
    this.removeEntitiesOnShoulder(); // carpet has already mocked this line by cancelDropShoulderEntities1()
}