Clean repo for open source release
Remove build artifacts, dev tool configs, unused dependencies, and third-party source dumps. Add proper README, update .gitignore, clean up Makefile.
This commit is contained in:
@@ -0,0 +1,323 @@
|
||||
package com.tiedup.remake.client.events;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.tiedup.remake.blocks.BlockMarker;
|
||||
import com.tiedup.remake.blocks.entity.MarkerBlockEntity;
|
||||
import com.tiedup.remake.cells.CellDataV2;
|
||||
import com.tiedup.remake.cells.CellRegistryV2;
|
||||
import com.tiedup.remake.cells.MarkerType;
|
||||
import com.tiedup.remake.client.renderer.CellOutlineRenderer;
|
||||
import com.tiedup.remake.core.TiedUpMod;
|
||||
import com.tiedup.remake.items.ItemAdminWand;
|
||||
import java.util.UUID;
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.player.LocalPlayer;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.client.event.RenderLevelStageEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
|
||||
/**
|
||||
* Event handler for rendering cell outlines when holding an admin wand.
|
||||
*
|
||||
* Phase: Kidnapper Revamp - Cell System
|
||||
*
|
||||
* Renders colored outlines around cell positions when:
|
||||
* - Player is holding an Admin Wand
|
||||
* - A cell is currently selected in the wand
|
||||
*
|
||||
* The outlines help builders visualize which blocks are part of the cell.
|
||||
*
|
||||
* Network sync: On dedicated servers, cell data is synced via PacketSyncCellData.
|
||||
* On integrated servers, direct access to server data is used as a fallback.
|
||||
*/
|
||||
@Mod.EventBusSubscriber(
|
||||
modid = TiedUpMod.MOD_ID,
|
||||
bus = Mod.EventBusSubscriber.Bus.FORGE,
|
||||
value = Dist.CLIENT
|
||||
)
|
||||
public class CellHighlightHandler {
|
||||
|
||||
// Client-side cache of cell data (synced from server via PacketSyncCellData)
|
||||
private static final java.util.Map<UUID, CellDataV2> syncedCells =
|
||||
new java.util.concurrent.ConcurrentHashMap<>();
|
||||
|
||||
// Legacy single-cell cache for backward compatibility
|
||||
private static CellDataV2 cachedCellData = null;
|
||||
private static UUID cachedCellId = null;
|
||||
|
||||
/**
|
||||
* Render cell outlines after translucent blocks.
|
||||
*/
|
||||
@SubscribeEvent
|
||||
public static void onRenderLevelStage(RenderLevelStageEvent event) {
|
||||
// Only render after translucent stage (so outlines appear on top)
|
||||
if (
|
||||
event.getStage() !=
|
||||
RenderLevelStageEvent.Stage.AFTER_TRANSLUCENT_BLOCKS
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
LocalPlayer player = mc.player;
|
||||
|
||||
if (player == null) return;
|
||||
|
||||
// Check if player is holding an Admin Wand
|
||||
ItemStack mainHand = player.getMainHandItem();
|
||||
ItemStack offHand = player.getOffhandItem();
|
||||
|
||||
boolean holdingAdminWand =
|
||||
mainHand.getItem() instanceof ItemAdminWand ||
|
||||
offHand.getItem() instanceof ItemAdminWand;
|
||||
|
||||
if (!holdingAdminWand) {
|
||||
cachedCellData = null;
|
||||
cachedCellId = null;
|
||||
return;
|
||||
}
|
||||
|
||||
PoseStack poseStack = event.getPoseStack();
|
||||
Camera camera = event.getCamera();
|
||||
|
||||
// If holding Admin Wand, render nearby structure markers and preview
|
||||
renderNearbyStructureMarkers(poseStack, camera, player);
|
||||
renderAdminWandPreview(poseStack, camera, player, mainHand, offHand);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a preview outline showing where the Admin Wand will place a marker.
|
||||
*/
|
||||
private static void renderAdminWandPreview(
|
||||
PoseStack poseStack,
|
||||
Camera camera,
|
||||
LocalPlayer player,
|
||||
ItemStack mainHand,
|
||||
ItemStack offHand
|
||||
) {
|
||||
// Get the block the player is looking at
|
||||
net.minecraft.world.phys.HitResult hitResult =
|
||||
Minecraft.getInstance().hitResult;
|
||||
if (
|
||||
hitResult == null ||
|
||||
hitResult.getType() != net.minecraft.world.phys.HitResult.Type.BLOCK
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
net.minecraft.world.phys.BlockHitResult blockHit =
|
||||
(net.minecraft.world.phys.BlockHitResult) hitResult;
|
||||
BlockPos targetPos = blockHit.getBlockPos().above(); // Marker goes above the clicked block
|
||||
|
||||
// Get the current marker type from the wand
|
||||
MarkerType type;
|
||||
if (mainHand.getItem() instanceof ItemAdminWand) {
|
||||
type = ItemAdminWand.getCurrentType(mainHand);
|
||||
} else {
|
||||
type = ItemAdminWand.getCurrentType(offHand);
|
||||
}
|
||||
|
||||
Vec3 cameraPos = camera.getPosition();
|
||||
float[] color = CellOutlineRenderer.getColorForType(type);
|
||||
|
||||
// Make preview semi-transparent and pulsing
|
||||
float alpha =
|
||||
0.5f + 0.3f * (float) Math.sin(System.currentTimeMillis() / 200.0);
|
||||
float[] previewColor = { color[0], color[1], color[2], alpha };
|
||||
|
||||
// Setup rendering (depth test off so preview shows through blocks)
|
||||
com.mojang.blaze3d.systems.RenderSystem.enableBlend();
|
||||
com.mojang.blaze3d.systems.RenderSystem.defaultBlendFunc();
|
||||
com.mojang.blaze3d.systems.RenderSystem.disableDepthTest();
|
||||
com.mojang.blaze3d.systems.RenderSystem.depthMask(false);
|
||||
com.mojang.blaze3d.systems.RenderSystem.setShader(
|
||||
net.minecraft.client.renderer.GameRenderer::getPositionColorShader
|
||||
);
|
||||
|
||||
CellOutlineRenderer.renderFilledBlock(
|
||||
poseStack,
|
||||
targetPos,
|
||||
cameraPos,
|
||||
previewColor
|
||||
);
|
||||
|
||||
com.mojang.blaze3d.systems.RenderSystem.depthMask(true);
|
||||
com.mojang.blaze3d.systems.RenderSystem.enableDepthTest();
|
||||
com.mojang.blaze3d.systems.RenderSystem.disableBlend();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render outlines for nearby structure markers (markers without cell IDs).
|
||||
*/
|
||||
private static void renderNearbyStructureMarkers(
|
||||
PoseStack poseStack,
|
||||
Camera camera,
|
||||
LocalPlayer player
|
||||
) {
|
||||
Level level = player.level();
|
||||
BlockPos playerPos = player.blockPosition();
|
||||
Vec3 cameraPos = camera.getPosition();
|
||||
|
||||
// Collect markers first to check if we need to render anything
|
||||
java.util.List<
|
||||
java.util.Map.Entry<BlockPos, MarkerType>
|
||||
> markersToRender = new java.util.ArrayList<>();
|
||||
|
||||
// Scan in a 32-block radius for structure markers
|
||||
int radius = 32;
|
||||
|
||||
for (int x = -radius; x <= radius; x++) {
|
||||
for (int y = -radius / 2; y <= radius / 2; y++) {
|
||||
for (int z = -radius; z <= radius; z++) {
|
||||
BlockPos pos = playerPos.offset(x, y, z);
|
||||
|
||||
if (
|
||||
level.getBlockState(pos).getBlock() instanceof
|
||||
BlockMarker
|
||||
) {
|
||||
BlockEntity be = level.getBlockEntity(pos);
|
||||
if (be instanceof MarkerBlockEntity marker) {
|
||||
// Only render structure markers (no cell ID)
|
||||
if (marker.getCellId() == null) {
|
||||
markersToRender.add(
|
||||
java.util.Map.entry(
|
||||
pos,
|
||||
marker.getMarkerType()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Only setup rendering if we have markers to render
|
||||
if (!markersToRender.isEmpty()) {
|
||||
// Setup rendering state (depth test off so markers show through blocks)
|
||||
com.mojang.blaze3d.systems.RenderSystem.enableBlend();
|
||||
com.mojang.blaze3d.systems.RenderSystem.defaultBlendFunc();
|
||||
com.mojang.blaze3d.systems.RenderSystem.disableDepthTest();
|
||||
com.mojang.blaze3d.systems.RenderSystem.depthMask(false);
|
||||
com.mojang.blaze3d.systems.RenderSystem.setShader(
|
||||
net.minecraft.client.renderer
|
||||
.GameRenderer::getPositionColorShader
|
||||
);
|
||||
|
||||
for (var entry : markersToRender) {
|
||||
BlockPos pos = entry.getKey();
|
||||
MarkerType type = entry.getValue();
|
||||
float[] baseColor = CellOutlineRenderer.getColorForType(type);
|
||||
// Semi-transparent fill
|
||||
float[] fillColor = {
|
||||
baseColor[0],
|
||||
baseColor[1],
|
||||
baseColor[2],
|
||||
0.4f,
|
||||
};
|
||||
CellOutlineRenderer.renderFilledBlock(
|
||||
poseStack,
|
||||
pos,
|
||||
cameraPos,
|
||||
fillColor
|
||||
);
|
||||
}
|
||||
|
||||
// Restore rendering state
|
||||
com.mojang.blaze3d.systems.RenderSystem.depthMask(true);
|
||||
com.mojang.blaze3d.systems.RenderSystem.enableDepthTest();
|
||||
com.mojang.blaze3d.systems.RenderSystem.disableBlend();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cell data on client side.
|
||||
* First checks the network-synced cache, then falls back to integrated server access.
|
||||
*
|
||||
* @param cellId The cell UUID to look up
|
||||
* @return CellDataV2 if found, null otherwise
|
||||
*/
|
||||
private static CellDataV2 getCellDataClient(UUID cellId) {
|
||||
if (cellId == null) return null;
|
||||
|
||||
// Priority 1: Check network-synced cache (works on dedicated servers)
|
||||
CellDataV2 synced = syncedCells.get(cellId);
|
||||
if (synced != null) {
|
||||
return synced;
|
||||
}
|
||||
|
||||
// Priority 2: Check legacy single-cell cache
|
||||
if (cellId.equals(cachedCellId) && cachedCellData != null) {
|
||||
return cachedCellData;
|
||||
}
|
||||
|
||||
// Priority 3: On integrated server, access server level directly (fallback)
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
if (mc.getSingleplayerServer() != null) {
|
||||
ServerLevel serverLevel = mc.getSingleplayerServer().overworld();
|
||||
if (serverLevel != null) {
|
||||
CellRegistryV2 registry = CellRegistryV2.get(serverLevel);
|
||||
CellDataV2 cell = registry.getCell(cellId);
|
||||
if (cell != null) {
|
||||
// Cache for future use
|
||||
cachedCellId = cellId;
|
||||
cachedCellData = cell;
|
||||
return cell;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Not found - on dedicated server, packet hasn't arrived yet
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update cached cell data (called from network sync - PacketSyncCellData).
|
||||
* Stores in both the synced map and legacy cache for compatibility.
|
||||
*
|
||||
* @param cell The cell data received from server
|
||||
*/
|
||||
public static void updateCachedCell(CellDataV2 cell) {
|
||||
if (cell != null) {
|
||||
// Store in synced map
|
||||
syncedCells.put(cell.getId(), cell);
|
||||
|
||||
// Also update legacy cache
|
||||
cachedCellId = cell.getId();
|
||||
cachedCellData = cell;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a cell from the cache (e.g., when cell is deleted).
|
||||
*
|
||||
* @param cellId The cell UUID to remove
|
||||
*/
|
||||
public static void removeCachedCell(UUID cellId) {
|
||||
if (cellId != null) {
|
||||
syncedCells.remove(cellId);
|
||||
if (cellId.equals(cachedCellId)) {
|
||||
cachedCellId = null;
|
||||
cachedCellData = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all cached cell data.
|
||||
* Called when disconnecting from server or on dimension change.
|
||||
*/
|
||||
public static void clearCache() {
|
||||
syncedCells.clear();
|
||||
cachedCellId = null;
|
||||
cachedCellData = null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user