diff --git a/build.gradle b/build.gradle index 218e9568c..bd50ab39b 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ import com.modrinth.minotaur.TaskModrinthUpload plugins { id 'fabric-loom' version '0.9-SNAPSHOT' id 'io.github.juuxel.loom-quiltflower' version '1.3.0' - id 'org.cadixdev.licenser' version '0.6.0' + id 'org.cadixdev.licenser' version '0.6.1' id 'com.matthewprenger.cursegradle' version '1.4.0' id 'com.jfrog.artifactory' version '4.21.0' id 'org.ajoberstar.grgit' version '3.1.1' diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e5338d370..ffed3a254 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/requiem-api/src/main/java/ladysnake/requiem/api/v1/block/VagrantTargetableBlock.java b/requiem-api/src/main/java/ladysnake/requiem/api/v1/block/VagrantTargetableBlock.java index 5950b9f84..55b5f5da5 100644 --- a/requiem-api/src/main/java/ladysnake/requiem/api/v1/block/VagrantTargetableBlock.java +++ b/requiem-api/src/main/java/ladysnake/requiem/api/v1/block/VagrantTargetableBlock.java @@ -21,6 +21,7 @@ import net.fabricmc.fabric.api.lookup.v1.block.BlockApiLookup; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.util.Identifier; +import net.minecraft.util.math.BlockPos; import org.apiguardian.api.API; /** @@ -34,5 +35,5 @@ public interface VagrantTargetableBlock { Identifier getTargetedIcon(); - boolean canBeUsedByVagrant(PlayerEntity player); + boolean canBeUsedByVagrant(BlockPos blockPos, PlayerEntity player); } diff --git a/src/main/java/ladysnake/requiem/client/RequiemTargetHandler.java b/src/main/java/ladysnake/requiem/client/RequiemTargetHandler.java index 3eb7a6a9b..a1e448607 100644 --- a/src/main/java/ladysnake/requiem/client/RequiemTargetHandler.java +++ b/src/main/java/ladysnake/requiem/client/RequiemTargetHandler.java @@ -40,6 +40,7 @@ import ladysnake.requiem.api.v1.entity.ability.AbilityType; import ladysnake.requiem.api.v1.event.minecraft.client.CrosshairRenderCallback; import ladysnake.requiem.api.v1.event.minecraft.client.UpdateTargetedEntityCallback; +import ladysnake.requiem.api.v1.remnant.RemnantComponent; import ladysnake.requiem.core.ability.PlayerAbilityController; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.DrawableHelper; @@ -121,10 +122,11 @@ public void onCrosshairRender(MatrixStack matrices, int scaledWidth, int scaledH float f = abilityController.getCooldownProgress(renderedType); if (abilityController.getTargetedEntity(renderedType) == null + && RemnantComponent.isIncorporeal(this.client.player) && this.client.crosshairTarget instanceof BlockHitResult bhr) { VagrantTargetableBlock targetable = VagrantTargetableBlock.LOOKUP.find(this.client.world, bhr.getBlockPos(), null); if (targetable != null) { - drawCrosshairIcon(matrices, scaledWidth, scaledHeight, targetable.getTargetedIcon(), targetable.canBeUsedByVagrant(client.player) ? 1 : 0); + drawCrosshairIcon(matrices, scaledWidth, scaledHeight, targetable.getTargetedIcon(), targetable.canBeUsedByVagrant(bhr.getBlockPos(), client.player) ? 1 : 0); return; } } diff --git a/src/main/java/ladysnake/requiem/common/block/RiftRunestoneBlock.java b/src/main/java/ladysnake/requiem/common/block/RiftRunestoneBlock.java index e903ffdf8..40a26bdb0 100644 --- a/src/main/java/ladysnake/requiem/common/block/RiftRunestoneBlock.java +++ b/src/main/java/ladysnake/requiem/common/block/RiftRunestoneBlock.java @@ -129,7 +129,10 @@ public Identifier getTargetedIcon() { } @Override - public boolean canBeUsedByVagrant(PlayerEntity player) { + public boolean canBeUsedByVagrant(BlockPos blockPos, PlayerEntity player) { + boolean powered = RunestoneBlockEntity.findObeliskOrigin(player.world, blockPos) + .map(origin -> player.world.getBlockEntity(origin)).map(be -> be instanceof RunestoneBlockEntity runestone && runestone.isPowered()).orElse(false); + if (!powered) return false; StatusEffectInstance statusEffect = player.getStatusEffect(RequiemStatusEffects.ATTRITION); return statusEffect == null || statusEffect.getAmplifier() < AttritionStatusEffect.MAX_LEVEL; } diff --git a/src/main/java/ladysnake/requiem/common/block/RunestoneBlockEntity.java b/src/main/java/ladysnake/requiem/common/block/RunestoneBlockEntity.java index 0d28dcb26..e1f6982b7 100644 --- a/src/main/java/ladysnake/requiem/common/block/RunestoneBlockEntity.java +++ b/src/main/java/ladysnake/requiem/common/block/RunestoneBlockEntity.java @@ -48,6 +48,7 @@ import ladysnake.requiem.common.particle.RequiemParticleTypes; import ladysnake.requiem.common.sound.RequiemSoundEvents; import ladysnake.requiem.common.tag.RequiemBlockTags; +import net.fabricmc.fabric.api.block.entity.BlockEntityClientSerializable; import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntity; import net.minecraft.entity.player.PlayerEntity; @@ -58,11 +59,7 @@ import net.minecraft.tag.BlockTags; import net.minecraft.text.Text; import net.minecraft.util.dynamic.GlobalPos; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Box; -import net.minecraft.util.math.Direction; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.*; import net.minecraft.world.BlockView; import net.minecraft.world.World; import org.jetbrains.annotations.Nullable; @@ -73,7 +70,7 @@ import java.util.UUID; import java.util.function.Consumer; -public class RunestoneBlockEntity extends BlockEntity { +public class RunestoneBlockEntity extends BlockEntity implements BlockEntityClientSerializable { public static final Direction[] OBELISK_SIDES = {Direction.SOUTH, Direction.EAST, Direction.NORTH, Direction.WEST}; public static final int POWER_ATTEMPTS = 6; public static final int MAX_OBELISK_CORE_WIDTH = 5; @@ -88,6 +85,7 @@ public class RunestoneBlockEntity extends BlockEntity { private @Nullable UUID recordUuid; private int obeliskCoreWidth = 0; private int obeliskCoreHeight = 0; + private boolean powered; public RunestoneBlockEntity(BlockPos pos, BlockState state) { super(RequiemBlockEntities.RUNIC_OBSIDIAN, pos, state); @@ -109,9 +107,16 @@ public static void tick(World world, BlockPos pos, BlockState state, RunestoneBl int obeliskWidth = be.obeliskCoreWidth; Vec3d obeliskCenter = getObeliskCenter(pos, obeliskWidth); - if (!be.levels.isEmpty() && be.findPowerSource((ServerWorld) world, obeliskCenter, getRange(obeliskWidth))) { + if (!be.levels.isEmpty() && findPowerSource((ServerWorld) world, obeliskCenter, getRange(obeliskWidth))) { + if (!be.powered) { + be.powered = true; + be.sync(); + } be.applyPlayerEffects(world, pos); world.playSound(null, pos, RequiemSoundEvents.BLOCK_OBELISK_AMBIENT, SoundCategory.BLOCKS, 1.0F, 1.4F); + } else if (be.powered) { + be.powered = false; + be.sync(); } } } @@ -201,6 +206,21 @@ public int getPowerLevel() { return this.obeliskCoreHeight; } + @Override + public void fromClientTag(NbtCompound tag) { + this.powered = tag.getBoolean("powered"); + } + + @Override + public NbtCompound toClientTag(NbtCompound tag) { + tag.putBoolean("powered", this.powered); + return tag; + } + + public boolean isPowered() { + return powered; + } + private void refreshStructure(BlockState state) { assert this.world != null; this.levels.clear(); diff --git a/src/main/java/ladysnake/requiem/common/screen/RiftScreenHandler.java b/src/main/java/ladysnake/requiem/common/screen/RiftScreenHandler.java index 6d32f2636..c0849d516 100644 --- a/src/main/java/ladysnake/requiem/common/screen/RiftScreenHandler.java +++ b/src/main/java/ladysnake/requiem/common/screen/RiftScreenHandler.java @@ -77,7 +77,7 @@ public BlockPos getSource() { @Override public boolean canUse(PlayerEntity player) { - return RemnantComponent.isIncorporeal(player) && canBeUsedBy.test(player) && RequiemBlocks.RIFT_RUNE.canBeUsedByVagrant(player); + return RemnantComponent.isIncorporeal(player) && canBeUsedBy.test(player) && RequiemBlocks.RIFT_RUNE.canBeUsedByVagrant(this.source, player); } public void useRift(ServerPlayerEntity player, BlockPos target) { diff --git a/src/main/java/ladysnake/requiem/mixin/client/remnant/GameRendererMixin.java b/src/main/java/ladysnake/requiem/mixin/client/remnant/GameRendererMixin.java index b6954a582..95c2dfd67 100644 --- a/src/main/java/ladysnake/requiem/mixin/client/remnant/GameRendererMixin.java +++ b/src/main/java/ladysnake/requiem/mixin/client/remnant/GameRendererMixin.java @@ -132,7 +132,7 @@ private void cancelBlockOutlineRender(CallbackInfoReturnable cir) { BlockState targetedBlock = world.getBlockState(bhr.getBlockPos()); if (targetedBlock.isIn(RequiemBlockTags.SOUL_INTERACTABLE)) { VagrantTargetableBlock itf = VagrantTargetableBlock.LOOKUP.find(world, bhr.getBlockPos(), targetedBlock, null, null); - return itf == null || itf.canBeUsedByVagrant(this.client.player); + return itf == null || itf.canBeUsedByVagrant(bhr.getBlockPos(), this.client.player); } }