GTNewHorizons / Hodgepodge

A HodgePodge of patches
GNU Lesser General Public License v3.0
39 stars 62 forks source link

fix: morpheus not properly waking players, not awarding buffs for sleeping #412

Closed leumasme closed 3 months ago

leumasme commented 3 months ago

Closes https://github.com/GTNewHorizons/GT-New-Horizons-Modpack/issues/16893

Morpheus doesn't actually wake players when a new day starts, it only sets the day time. This causes players to instead wake up automatically on the next tick as they're in a bed while its day. This isn't good, and causes the GT5-Unofficial buff you get after sleeping to not be awarded.

This uses an Accessor mixin to call wakeAllPlayers. Because this has to run early but the actual Morpheus fix has to run late, they're split into two mixins. Maybe reorganize the Accessor mixin to be in the general/minecraft section instead of Morpheus (+change description)? Not sure; this is my first hodgepodge PR

Transforms the Morpheus Method

private void advanceToMorning(World world) {
    try {
        ((INewDayHandler)MorpheusRegistry.registry.get(world.provider.dimensionId)).startNewDay();
    } catch (Exception var3) {
        Morpheus.mLog.error("Exception caught while starting a new day for dimension " + world.provider.dimensionId);
    }

    if (!(Boolean)this.alertSent.get(world.provider.dimensionId)) {
        this.alertPlayers(new ChatComponentText(DateHandler.getMorningText()), world);
        ((WorldSleepState)Morpheus.playerSleepStatus.get(world.provider.dimensionId)).wakeAllPlayers();
        this.alertSent.put(world.provider.dimensionId, true);
    }

    world.provider.resetRainAndThunder();
}

into the equivalent of

private void advanceToMorning(World world) {
    try {
        ((INewDayHandler)MorpheusRegistry.registry.get(world.provider.dimensionId)).startNewDay();
    } catch (Exception var3) {
        Morpheus.mLog.error("Exception caught while starting a new day for dimension " + world.provider.dimensionId);
    }

    if (!(Boolean)this.alertSent.get(world.provider.dimensionId)) {
        this.alertPlayers(new ChatComponentText(DateHandler.getMorningText()), world);
        ((WorldSleepState)Morpheus.playerSleepStatus.get(world.provider.dimensionId)).wakeAllPlayers();
        this.alertSent.put(world.provider.dimensionId, true);
    }
   /* Inject Start */
    if (world instanceof WorldServer worldServer) {
        worldServer.wakeAllPlayers();
        return;
    }
   /* Inject End */
    world.provider.resetRainAndThunder();
}

The return before the call to resetRainAndThunder is intentional, as wakeAllPlayers also calls resetRainAndThunder

Tested ingame to verify that it works. The behavior is now

leumasme commented 3 months ago

https://github.com/user-attachments/assets/dceedb0c-100e-4a88-bfa1-914948120cb5

Alexdoru commented 3 months ago

looks good to me