pala M-grinder-2: detecteur multibloc 3x3x3 + diagnostic clic droit
This commit is contained in:
@@ -553,6 +553,10 @@ avant M4 (TODO:crafts-machines).
|
|||||||
(pattern frame UNVERIFIED : positions titane non visibles wiki). GUI + multibloc + tetes +
|
(pattern frame UNVERIFIED : positions titane non visibles wiki). GUI + multibloc + tetes +
|
||||||
modifieurs : M-grinder-2/3. VERIFIE : build SUCCESSFUL, boot Done, 0 erreur. UNVERIFIED
|
modifieurs : M-grinder-2/3. VERIFIE : build SUCCESSFUL, boot Done, 0 erreur. UNVERIFIED
|
||||||
visuel (session client M-grinder-2).
|
visuel (session client M-grinder-2).
|
||||||
|
- M-grinder-2 LIVRE 2026-10-19 ~03:15 : detecteur multibloc PalaGrinder (3x3x3, totaux wiki
|
||||||
|
20F/5C/1B/1L recalcules, 4 rotations, lave source exigee) + diagnostic clic droit sur le
|
||||||
|
coeur. GUI + tetes + modifieurs : M-grinder-3. VERIFIE : build SUCCESSFUL, boot Done,
|
||||||
|
0 erreur. UNVERIFIED : orientation exacte du B (tableau wiki ambigu).
|
||||||
- Client/mod : boucle visuelle OPERATIONNELLE 2026-10-19 (Xvfb :99 + runClient SDL x11 +
|
- Client/mod : boucle visuelle OPERATIONNELLE 2026-10-19 (Xvfb :99 + runClient SDL x11 +
|
||||||
captures Java Robot + pilotage xdotool + vision_analyze) : menu, Select World, monde New World
|
captures Java Robot + pilotage xdotool + vision_analyze) : menu, Select World, monde New World
|
||||||
(creatif, cheats), /give, pose de bloc, inventaire, F3+T. Screens : scratch vis*.png.
|
(creatif, cheats), /give, pose de bloc, inventaire, F3+T. Screens : scratch vis*.png.
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import net.fabricmc.fabric.api.event.player.UseItemCallback;
|
|||||||
|
|
||||||
import fr.surviepote.pala.PalaBlocks;
|
import fr.surviepote.pala.PalaBlocks;
|
||||||
import fr.surviepote.pala.PalaItems;
|
import fr.surviepote.pala.PalaItems;
|
||||||
|
import fr.surviepote.pala.machine.PalaGrinder;
|
||||||
|
|
||||||
// Portage des procedures "clic droit" MCreator :
|
// Portage des procedures "clic droit" MCreator :
|
||||||
// - batons : ProcedureHealStick/ HyperJumpStick/ SpeedStick/ StickOfGod/ StrenghStickRightClickedInAir
|
// - batons : ProcedureHealStick/ HyperJumpStick/ SpeedStick/ StickOfGod/ StrenghStickRightClickedInAir
|
||||||
@@ -137,6 +138,16 @@ public final class PalaItemUseEvents {
|
|||||||
ItemStack stack = player.getItemInHand(hand);
|
ItemStack stack = player.getItemInHand(hand);
|
||||||
Item item = stack.isEmpty() ? null : stack.getItem();
|
Item item = stack.isEmpty() ? null : stack.getItem();
|
||||||
|
|
||||||
|
// --- Grinder : clic droit sur le coeur -> etat du multibloc (M-grinder-2).
|
||||||
|
// GUI + crafts en M-grinder-3 ; ici diagnostic seul (ne casse rien).
|
||||||
|
if (target.getBlock() == PalaBlocks.GRINDER_BLOCK) {
|
||||||
|
boolean formed = PalaGrinder.isFormed(sl, pos);
|
||||||
|
sp.sendSystemMessage(net.minecraft.network.chat.Component.literal(formed
|
||||||
|
? "§6[Grinder] §aStructure complete (20 frames, 5 casings, lave)."
|
||||||
|
: "§6[Grinder] §cStructure incomplete (attendu : 3x3x3, voir wiki)."));
|
||||||
|
return InteractionResult.SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
// --- Semis sur farmland (graine en main, dessus libre) ---
|
// --- Semis sur farmland (graine en main, dessus libre) ---
|
||||||
if (target.getBlock() == Blocks.FARMLAND && item != null) {
|
if (target.getBlock() == Blocks.FARMLAND && item != null) {
|
||||||
Block crop = null;
|
Block crop = null;
|
||||||
|
|||||||
@@ -0,0 +1,96 @@
|
|||||||
|
package fr.surviepote.pala.machine;
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.tags.FluidTags;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
|
||||||
|
import fr.surviepote.pala.PalaBlocks;
|
||||||
|
|
||||||
|
// M-grinder-2 (wiki grinder §2) : detection du multibloc 3x3x3 (20 frame + 5 casing +
|
||||||
|
// 1 block + 1 lave = 26 blocs + lave).
|
||||||
|
//
|
||||||
|
// Structure (totaux wiki VERIFIES par comptage : 8F+1C par couche haute/basse, 4F+3C+1B+1L
|
||||||
|
// au milieu) :
|
||||||
|
// couche -1 et +1 : F F F / F C F / F F F
|
||||||
|
// couche 0 : F C F / C L C / F B F (B = face sud en rotation 0)
|
||||||
|
// Le B peut etre sur n'importe quelle face horizontale : 4 rotations testees.
|
||||||
|
// UNVERIFIED : orientation exacte du B et ordre des couches (tableau wiki ambigu) —
|
||||||
|
// a confirmer en jeu (M-grinder-3). La detection ne casse rien si KO (message seulement).
|
||||||
|
public final class PalaGrinder {
|
||||||
|
|
||||||
|
private PalaGrinder() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// (dx, dy, dz, attendu) en rotation 0. Attendu : 'F' frame, 'C' casing, 'B' block, 'L' lave.
|
||||||
|
private static final Object[][] CELLS = cells();
|
||||||
|
|
||||||
|
private static Object[][] cells() {
|
||||||
|
java.util.List<Object[]> list = new java.util.ArrayList<>();
|
||||||
|
// Couches -1 et +1 : frame partout sauf casing au centre.
|
||||||
|
for (int dy : new int[]{-1, 1}) {
|
||||||
|
for (int dx = -1; dx <= 1; dx++) {
|
||||||
|
for (int dz = -1; dz <= 1; dz++) {
|
||||||
|
char expect = (dx == 0 && dz == 0) ? 'C' : 'F';
|
||||||
|
list.add(new Object[]{dx, dy, dz, expect});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Couche 0 : coins F, aretes N/S/E = C, arete sud = B, centre = L.
|
||||||
|
list.add(new Object[]{-1, 0, -1, 'F'});
|
||||||
|
list.add(new Object[]{0, 0, -1, 'C'});
|
||||||
|
list.add(new Object[]{1, 0, -1, 'F'});
|
||||||
|
list.add(new Object[]{-1, 0, 0, 'C'});
|
||||||
|
list.add(new Object[]{0, 0, 0, 'L'});
|
||||||
|
list.add(new Object[]{1, 0, 0, 'C'});
|
||||||
|
list.add(new Object[]{-1, 0, 1, 'F'});
|
||||||
|
list.add(new Object[]{0, 0, 1, 'B'});
|
||||||
|
list.add(new Object[]{1, 0, 1, 'F'});
|
||||||
|
return list.toArray(new Object[0][]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rotation 0-3 autour de Y : (x, z) -> (z, -x) applique r fois.
|
||||||
|
private static int[] rot(int x, int z, int r) {
|
||||||
|
for (int i = 0; i < r; i++) {
|
||||||
|
int nx = z;
|
||||||
|
int nz = -x;
|
||||||
|
x = nx;
|
||||||
|
z = nz;
|
||||||
|
}
|
||||||
|
return new int[]{x, z};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean match(ServerLevel level, BlockPos origin, int r) {
|
||||||
|
for (Object[] cell : CELLS) {
|
||||||
|
int[] xz = rot((int) cell[0], (int) cell[2], r);
|
||||||
|
BlockPos pos = origin.offset(xz[0], (int) cell[1], xz[1]);
|
||||||
|
char expect = (char) cell[3];
|
||||||
|
if (expect == 'L') {
|
||||||
|
if (!(level.getFluidState(pos).is(FluidTags.LAVA)
|
||||||
|
&& level.getFluidState(pos).isSource())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Block want = expect == 'F' ? PalaBlocks.GRINDER_FRAME
|
||||||
|
: expect == 'C' ? PalaBlocks.GRINDER_CASING : PalaBlocks.GRINDER_BLOCK;
|
||||||
|
if (level.getBlockState(pos).getBlock() != want) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Vrai si le GRINDER_BLOCK en origin est le coeur d'un multibloc forme (4 rotations). */
|
||||||
|
public static boolean isFormed(ServerLevel level, BlockPos origin) {
|
||||||
|
if (level.getBlockState(origin).getBlock() != PalaBlocks.GRINDER_BLOCK) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (int r = 0; r < 4; r++) {
|
||||||
|
if (match(level, origin, r)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
Reference in New Issue
Block a user