Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

分离定日镜服务端与客户端运算逻辑,添加定日镜扫描间隔配置文件,更改定日镜同步为仅加载时同步一次 #1011

Merged
merged 5 commits into from
Jul 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package dev.dubhe.anvilcraft.api.event.server.block;

import lombok.Getter;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.block.entity.BlockEntity;

@Getter
abstract class ServerBlockEntityEvent {
private final ServerLevel serverLevel;
private final BlockEntity blockEntity;

ServerBlockEntityEvent(ServerLevel serverLevel, BlockEntity blockEntity) {
this.serverLevel = serverLevel;
this.blockEntity = blockEntity;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package dev.dubhe.anvilcraft.api.event.server.block;

import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.block.entity.BlockEntity;

public class ServerBlockEntityLoadEvent extends ServerBlockEntityEvent {
public ServerBlockEntityLoadEvent(ServerLevel serverLevel, BlockEntity blockEntity) {
super(serverLevel, blockEntity);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package dev.dubhe.anvilcraft.api.event.server.block;

import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.block.entity.BlockEntity;

public class ServerBlockEntityUnloadEvent extends ServerBlockEntityEvent {
public ServerBlockEntityUnloadEvent(ServerLevel serverLevel, BlockEntity blockEntity) {
super(serverLevel, blockEntity);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,10 @@ public BlockEntity newBlockEntity(@NotNull BlockPos pos, @NotNull BlockState sta
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(
@NotNull Level level, @NotNull BlockState state, @NotNull BlockEntityType<T> type
) {
if (level.isClientSide) {
return null;
}
return createTickerHelper(
type,
ModBlockEntities.HELIOSTATS.get(),
(level1, blockPos, blockState, blockEntity) -> blockEntity.tick(level1)
(level1, blockPos, blockState, blockEntity) -> blockEntity.tick()
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package dev.dubhe.anvilcraft.block.entity;

import dev.dubhe.anvilcraft.AnvilCraft;
import dev.dubhe.anvilcraft.api.chargecollector.HeatedBlockRecorder;
import dev.dubhe.anvilcraft.api.entity.player.AnvilCraftBlockPlacer;
import dev.dubhe.anvilcraft.network.HeliostatsIrradiationPack;
import lombok.Getter;
import lombok.Setter;
import net.minecraft.client.Minecraft;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.ClipContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LightLayer;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
Expand All @@ -19,7 +20,10 @@
import org.jetbrains.annotations.NotNull;
import org.joml.Vector3f;

import java.util.Objects;

public class HeliostatsBlockEntity extends BlockEntity {
@Getter
private BlockPos irritatePos;
@Getter
@Setter
Expand All @@ -29,16 +33,16 @@ public class HeliostatsBlockEntity extends BlockEntity {
private Vector3f irritateVector3f = new Vector3f().normalize();
@Getter
@Setter
private float irritateDistance = 0;
@Getter
@Setter
private WorkResult workResult = WorkResult.SUCCESS;
private int surfaceVec3Hash = 0;
private Vec3 surfaceVec3 = new Vec3(0, 0, 0);

public HeliostatsBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState blockState) {
super(type, pos, blockState);
}

private Vec3 getSurfaceVec3(Vec3 vec31, Vec3 vec32) {
if (vec31.hashCode() + vec32.hashCode() == surfaceVec3Hash) return surfaceVec3;
if (level == null) return vec31;
if (!level.getBlockState(irritatePos.north()).isAir()
&& !level.getBlockState(irritatePos.south()).isAir()
Expand All @@ -52,6 +56,8 @@ private Vec3 getSurfaceVec3(Vec3 vec31, Vec3 vec32) {
float y = vec2.y > 0 ? 0.49f : -0.49f;
if (y / k < 0.5 && y / k > -0.5) return vec31.add(y, 0, y / k);
if (k * x < 0.5 && k * x > -0.5) return vec31.add(k * x, 0, x);
surfaceVec3Hash = vec31.hashCode() + vec32.hashCode();
surfaceVec3 = vec31;
return vec31;
}

Expand All @@ -66,36 +72,40 @@ public boolean setIrritatePos(BlockPos pos) {

private WorkResult validatePos(BlockPos irritatePos) {
normalVector3f = new Vector3f();
if (level == null) return WorkResult.UNKNOWN.synchronize(this);
if (irritatePos == null) return WorkResult.UNSPECIFIED_IRRADIATION_BLOCK.synchronize(this);
if (level == null) return WorkResult.UNKNOWN;
if (level.isClientSide && Minecraft.getInstance().player == null)
return WorkResult.UNKNOWN;
if (irritatePos == null) return WorkResult.UNSPECIFIED_IRRADIATION_BLOCK;
if (getBlockPos().getCenter().distanceTo(irritatePos.getCenter()) > 16)
return WorkResult.TOO_FAR.synchronize(this);
return WorkResult.TOO_FAR;
if (level.isRainingAt(getBlockPos().above())
|| level.getBrightness(LightLayer.SKY, getBlockPos().above()) != 15)
return WorkResult.NO_SUN.synchronize(this);
return WorkResult.NO_SUN;
Vec3 irritateVec3 = getSurfaceVec3(irritatePos.getCenter(), getBlockPos().getCenter());
BlockHitResult blockHitResult = level.clip(new ClipContext(
getBlockPos().getCenter().add(0f, 0.34f, 0f),
irritateVec3,
ClipContext.Block.OUTLINE,
ClipContext.Fluid.NONE,
AnvilCraftBlockPlacer.anvilCraftBlockPlacer.getPlayer())
level.isClientSide
? Objects.requireNonNull(Minecraft.getInstance().player)
: AnvilCraftBlockPlacer.anvilCraftBlockPlacer.getPlayer()
)
);
if (!blockHitResult.getBlockPos().equals(irritatePos))
return WorkResult.OBSCURED.synchronize(this);
return WorkResult.OBSCURED;
double sunAngle = level.getSunAngle(1);
sunAngle = sunAngle <= Math.PI / 2 * 3 ? sunAngle + Math.PI / 2 : sunAngle - Math.PI / 2 * 3;
if (sunAngle > Math.PI) return WorkResult.NO_SUN.synchronize(this);
if (sunAngle > Math.PI) return WorkResult.NO_SUN;
Vector3f sunVector3f = new Vector3f((float) Math.cos(sunAngle), (float) Math.sin(sunAngle), 0).normalize();
irritateVector3f = new Vector3f(
(float) (irritateVec3.x - getBlockPos().getX()),
(float) (irritateVec3.y - getBlockPos().getY()),
(float) (irritateVec3.z - getBlockPos().getZ())
).normalize();
irritateDistance = (float) (getBlockPos().getCenter().distanceTo(irritatePos.getCenter()) - 0.5);
normalVector3f = sunVector3f.add(irritateVector3f).div(2);
if (normalVector3f.y < 0) return WorkResult.NO_ROTATION_ANGLE.synchronize(this);
return WorkResult.SUCCESS.synchronize(this);
if (normalVector3f.y < 0) return WorkResult.NO_ROTATION_ANGLE;
return WorkResult.SUCCESS;
}

@Override
Expand All @@ -116,10 +126,13 @@ public void load(@NotNull CompoundTag tag) {
}

/**
*
* tick
*/
public void tick(Level level) {
if (level.isClientSide) return;
public void tick() {
if (level == null) return;
if (level.getGameTime() % (AnvilCraft.config.heliostatsDetectionInterval + 1) != 0) return;
if (irritatePos == null && level.isClientSide)
new HeliostatsIrradiationPack(getBlockPos(), irritatePos).send();
workResult = validatePos(irritatePos);
if (workResult.isWork()) {
HeatedBlockRecorder.getInstance(getLevel()).addOrIncrease(irritatePos, this);
Expand Down Expand Up @@ -161,20 +174,6 @@ public String getTranslateKey() {
return this.key;
}

/**
* 与客户端同步结果
*/
public WorkResult synchronize(HeliostatsBlockEntity blockEntity) {
new HeliostatsIrradiationPack(
blockEntity.getBlockPos(),
blockEntity.normalVector3f,
blockEntity.irritateVector3f,
blockEntity.irritateDistance,
this
).broadcast();
return this;
}

public boolean isWork() {
return this.equals(SUCCESS);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
package dev.dubhe.anvilcraft.client.renderer.blockentity;

import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import dev.dubhe.anvilcraft.block.entity.HeliostatsBlockEntity;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.resources.model.ModelResourceLocation;
import net.minecraft.core.Direction;
import net.minecraft.core.Vec3i;
import org.jetbrains.annotations.NotNull;
import org.joml.Quaternionf;
import org.joml.Vector3f;
Expand Down Expand Up @@ -40,16 +35,6 @@ public void render(@NotNull HeliostatsBlockEntity blockEntity,
) {
poseStack.pushPose();
poseStack.translate(0.5, 0.5625, 0.5);
/*
if (!blockEntity.getNormalVector3f().equals(new Vector3f())) {
final TextureAtlasSprite sprite = Minecraft.getInstance().getTextureAtlas(TextureAtlas.LOCATION_BLOCKS)
.apply(new ResourceLocation("block/white_concrete"));
poseStack.mulPose(new Quaternionf().rotateTo(new Vector3f(0, 1, 0), blockEntity.getIrritateVector3f()));
renderBox(
buffer.getBuffer(RenderType.translucentNoCrumbling()), poseStack,
blockEntity.getIrritateDistance(), sprite);
poseStack.mulPose(new Quaternionf().rotateTo(blockEntity.getIrritateVector3f(), new Vector3f(0, 1, 0)));
}*/
if (!blockEntity.getNormalVector3f().equals(new Vector3f())
&& !blockEntity.getNormalVector3f().equals(new Vector3f(Float.NaN))) {
poseStack.mulPose(new Quaternionf().rotateY(
Expand All @@ -72,70 +57,4 @@ public void render(@NotNull HeliostatsBlockEntity blockEntity,
);
poseStack.popPose();
}

@SuppressWarnings("unused")
private static void renderBox(
VertexConsumer consumer,
@NotNull PoseStack poseStack,
float maxY, TextureAtlasSprite sprite
) {
renderQuadX(consumer, poseStack,
(float) 0.375, (float) 0.375, (float) -0.375, maxY, (float) 0.375,
sprite, Direction.EAST.getNormal());
renderQuadX(consumer, poseStack,
(float) -0.375, (float) -0.375, (float) 0.375, maxY, (float) -0.375,
sprite, Direction.WEST.getNormal());
renderQuadZ(consumer, poseStack,
(float) 0.375, (float) 0.375, maxY, (float) 0,
sprite, Direction.SOUTH.getNormal());
renderQuadZ(consumer, poseStack,
(float) -0.375, (float) -0.375, (float) 0, maxY,
sprite, Direction.NORTH.getNormal());
}

private static void renderQuadX(
VertexConsumer consumer,
@NotNull PoseStack poseStack,
float minX, float maxX, float minZ, float maxY, float maxZ, TextureAtlasSprite sprite, Vec3i normal
) {
addVertex(consumer, poseStack, minX, maxY, minZ, sprite.getU1(), sprite.getV1(), normal);
addVertex(consumer, poseStack, minX, maxY, maxZ, sprite.getU0(), sprite.getV1(), normal);
addVertex(consumer, poseStack, maxX, (float) 0.0, maxZ, sprite.getU0(), sprite.getV0(), normal);
addVertex(consumer, poseStack, maxX, (float) 0.0, minZ, sprite.getU1(), sprite.getV0(), normal);
}

private static void renderQuadY(
VertexConsumer consumer,
@NotNull PoseStack poseStack,
float minY, float maxY, float minX, float maxX, TextureAtlasSprite sprite, Vec3i normal
) {
addVertex(consumer, poseStack, minX, minY, (float) -0.375, sprite.getU1(), sprite.getV1(), normal);
addVertex(consumer, poseStack, minX, minY, (float) 0.375, sprite.getU0(), sprite.getV1(), normal);
addVertex(consumer, poseStack, maxX, maxY, (float) 0.375, sprite.getU0(), sprite.getV0(), normal);
addVertex(consumer, poseStack, maxX, maxY, (float) -0.375, sprite.getU1(), sprite.getV0(), normal);
}

private static void renderQuadZ(
VertexConsumer consumer,
@NotNull PoseStack poseStack,
float minZ, float maxZ, float minY, float maxY, TextureAtlasSprite sprite, Vec3i normal
) {
addVertex(consumer, poseStack, (float) -0.375, maxY, minZ, sprite.getU1(), sprite.getV1(), normal);
addVertex(consumer, poseStack, (float) 0.375, maxY, minZ, sprite.getU0(), sprite.getV1(), normal);
addVertex(consumer, poseStack, (float) 0.375, minY, maxZ, sprite.getU0(), sprite.getV0(), normal);
addVertex(consumer, poseStack, (float) -0.375, minY, maxZ, sprite.getU1(), sprite.getV0(), normal);
}

private static void addVertex(
@NotNull VertexConsumer consumer, @NotNull PoseStack poseStack,
float x, float y, float z, float u, float v, Vec3i normal) {
consumer
.vertex(poseStack.last().pose(), x, y, z)
.color(1f, 1f, 1f, (float) 0.1)
.uv(u, v)
.overlayCoords(OverlayTexture.NO_OVERLAY)
.uv2(0xF000F0)
.normal(normal.getX(), normal.getY(), normal.getZ())
.endVertex();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,12 @@ public class AnvilCraftConfig implements ConfigData {
@ConfigEntry.BoundedDiscrete(min = 0, max = 100)
public int inductionLightBlockRipeningRange = 5;

@Comment("The number of ticks between heliostat detections")
@ConfigEntry.Gui.Tooltip
@ConfigEntry.BoundedDiscrete(max = 20, min = 1)
@SerializedName("Heliostats detection interval")
public int heliostatsDetectionInterval = 4;

public static class PowerConverter implements ConfigData {
@Comment("The working interval of power converters")
@ConfigEntry.Gui.Tooltip
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package dev.dubhe.anvilcraft.event;

import dev.anvilcraft.lib.event.SubscribeEvent;
import dev.dubhe.anvilcraft.api.chargecollector.ChargeCollectorManager;
import dev.dubhe.anvilcraft.api.chargecollector.HeatedBlockRecorder;
import dev.dubhe.anvilcraft.api.event.server.block.ServerBlockEntityLoadEvent;
import dev.dubhe.anvilcraft.api.power.IPowerComponent;
import dev.dubhe.anvilcraft.api.power.PowerGrid;
import dev.dubhe.anvilcraft.api.world.load.LevelLoadManager;
import dev.dubhe.anvilcraft.block.entity.ChargeCollectorBlockEntity;
import dev.dubhe.anvilcraft.block.entity.HeliostatsBlockEntity;
import dev.dubhe.anvilcraft.block.entity.OverseerBlockEntity;

public class ServerBlockEntityEventListener {

/**
* @param event 服务端方块实体加载事件
*/
@SuppressWarnings("unused")
@SubscribeEvent
public void onLoad(ServerBlockEntityLoadEvent event) {
if (event.getBlockEntity() instanceof IPowerComponent component) {
PowerGrid.addComponent(component);
}
if (event.getBlockEntity() instanceof ChargeCollectorBlockEntity chargeCollector) {
ChargeCollectorManager.getInstance(event.getServerLevel()).addChargeCollector(chargeCollector);
}
}

/**
* @param event 服务端方块实体卸载事件
*/
@SuppressWarnings("unused")
@SubscribeEvent
public void onUnload(ServerBlockEntityLoadEvent event) {
if (event.getBlockEntity() instanceof IPowerComponent component) {
PowerGrid.removeComponent(component);
}
if (event.getBlockEntity() instanceof ChargeCollectorBlockEntity chargeCollector) {
ChargeCollectorManager.getInstance(event.getServerLevel()).removeChargeCollector(chargeCollector);
return;
}
if (event.getBlockEntity() instanceof OverseerBlockEntity overseerBlockEntity) {
LevelLoadManager.unregister(overseerBlockEntity.getBlockPos(), event.getServerLevel());
return;
}
if (event.getBlockEntity() instanceof HeliostatsBlockEntity heliostatsBlockEntity) {
HeatedBlockRecorder.getInstance(event.getServerLevel()).remove(
heliostatsBlockEntity.getIrritatePos(),
heliostatsBlockEntity
);
}
}
}
2 changes: 2 additions & 0 deletions common/src/main/java/dev/dubhe/anvilcraft/init/ModEvents.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import dev.dubhe.anvilcraft.event.anvil.GiantAnvilMultiblockCraftingEventListener;
import dev.dubhe.anvilcraft.event.LightningEventListener;
import dev.dubhe.anvilcraft.event.PlayerEventListener;
import dev.dubhe.anvilcraft.event.ServerBlockEntityEventListener;
import dev.dubhe.anvilcraft.event.client.ClientPlayerDisconnectEventListener;
import dev.dubhe.anvilcraft.event.server.ServerEventListener;

Expand All @@ -28,6 +29,7 @@ public static void register() {
AnvilCraft.EVENT_BUS.register(new AnvilHitBlockDevourerEventListener());
AnvilCraft.EVENT_BUS.register(new AnvilHitImpactPileEventListener());
AnvilCraft.EVENT_BUS.register(new GiantAnvilMultiblockCraftingEventListener());
AnvilCraft.EVENT_BUS.register(new ServerBlockEntityEventListener());
AnvilCraft.EVENT_BUS.register(new ClientPlayerDisconnectEventListener());
}
}
Loading
Loading