mirror of
https://github.com/FabricMC/fabric.git
synced 2025-04-21 03:10:54 -04:00
Sleeping event fixes (#1681)
* Un-hardcode FACING property checks from only BedBlocks * Use a better injection point for EntitySleepEvents.ALLOW_BED * Fix #1680 * Bump entity events version * Clarify javadoc * Let's not forget license headers * Add a note about the vanilla bug * Update BedBlockMixin.java
This commit is contained in:
parent
fe42ded042
commit
87cc6e4c30
6 changed files with 51 additions and 13 deletions
fabric-entity-events-v1
|
@ -1,5 +1,5 @@
|
|||
archivesBaseName = "fabric-entity-events-v1"
|
||||
version = getSubprojectVersion(project, "1.2.2")
|
||||
version = getSubprojectVersion(project, "1.2.3")
|
||||
|
||||
moduleDependencies(project, [
|
||||
'fabric-api-base'
|
||||
|
|
|
@ -296,6 +296,7 @@ public final class EntitySleepEvents {
|
|||
public interface ModifySleepingDirection {
|
||||
/**
|
||||
* Modifies or provides a sleeping direction for a block.
|
||||
* The sleeping direction is where a player's head is pointing when they're sleeping.
|
||||
*
|
||||
* @param entity the sleeping entity
|
||||
* @param sleepingPos the position of the block slept on
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.fabricmc.fabric.mixin.entity.event;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import net.minecraft.block.BedBlock;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
|
||||
@Mixin(BedBlock.class)
|
||||
abstract class BedBlockMixin {
|
||||
// Synthetic lambda body for Either.ifLeft in onUse
|
||||
@Inject(method = "method_19283", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;sendMessage(Lnet/minecraft/text/Text;Z)V"), cancellable = true)
|
||||
private static void onOnUse(PlayerEntity player, PlayerEntity.SleepFailureReason reason, CallbackInfo info) {
|
||||
// EntitySleepEvents.ALLOW_SLEEPING allows modders to return SleepFailureReason instances
|
||||
// with a null message, which vanilla's code doesn't guard against. This prevents a (luckily caught) NPE
|
||||
// when a failure reason like that is returned from the event.
|
||||
// The NPE can also be reproduced in vanilla with custom data pack dimensions (MC-235035, which is also fixed here).
|
||||
if (reason.toText() == null) {
|
||||
info.cancel();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -81,17 +81,14 @@ abstract class LivingEntityMixin {
|
|||
}
|
||||
}
|
||||
|
||||
@Inject(method = "isSleepingInBed", at = @At("RETURN"), cancellable = true)
|
||||
private void onIsSleepingInBed(CallbackInfoReturnable<Boolean> info) {
|
||||
BlockPos sleepingPos = getSleepingPosition().orElse(null);
|
||||
// Synthetic lambda body for Optional.map in isSleepingInBed
|
||||
@Inject(method = "method_18405", at = @At("RETURN"), cancellable = true)
|
||||
private void onIsSleepingInBed(BlockPos sleepingPos, CallbackInfoReturnable<Boolean> info) {
|
||||
BlockState bedState = ((LivingEntity) (Object) this).world.getBlockState(sleepingPos);
|
||||
ActionResult result = EntitySleepEvents.ALLOW_BED.invoker().allowBed((LivingEntity) (Object) this, sleepingPos, bedState, info.getReturnValueZ());
|
||||
|
||||
if (sleepingPos != null) {
|
||||
BlockState bedState = ((LivingEntity) (Object) this).world.getBlockState(sleepingPos);
|
||||
ActionResult result = EntitySleepEvents.ALLOW_BED.invoker().allowBed((LivingEntity) (Object) this, sleepingPos, bedState, info.getReturnValueZ());
|
||||
|
||||
if (result != ActionResult.PASS) {
|
||||
info.setReturnValue(result.isAccepted());
|
||||
}
|
||||
if (result != ActionResult.PASS) {
|
||||
info.setReturnValue(result.isAccepted());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||
|
||||
import net.minecraft.block.BedBlock;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
|
@ -88,7 +87,7 @@ abstract class ServerPlayerEntityMixin extends LivingEntityMixin {
|
|||
|
||||
@Redirect(method = "trySleep", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/BlockState;get(Lnet/minecraft/state/property/Property;)Ljava/lang/Comparable;"))
|
||||
private Comparable<?> redirectSleepDirection(BlockState state, Property<?> property, BlockPos pos) {
|
||||
Direction initial = state.getBlock() instanceof BedBlock ? (Direction) state.get(property) : null;
|
||||
Direction initial = state.contains(property) ? (Direction) state.get(property) : null;
|
||||
return EntitySleepEvents.MODIFY_SLEEPING_DIRECTION.invoker().modifySleepDirection((LivingEntity) (Object) this, pos, initial);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
"package": "net.fabricmc.fabric.mixin.entity.event",
|
||||
"compatibilityLevel": "JAVA_16",
|
||||
"mixins": [
|
||||
"BedBlockMixin",
|
||||
"EntityMixin",
|
||||
"LivingEntityMixin",
|
||||
"PlayerEntityMixin",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue