Skip to content

Commit

Permalink
Y rotation multipart compat
Browse files Browse the repository at this point in the history
  • Loading branch information
gtosh4 committed Jul 15, 2023
1 parent 0b5d4ee commit f133ab3
Show file tree
Hide file tree
Showing 6 changed files with 182 additions and 80 deletions.
2 changes: 2 additions & 0 deletions dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ dependencies {

devOnlyNonPublishable 'com.github.GTNewHorizons:ArchitectureCraft:1.8.6'
devOnlyNonPublishable 'com.github.GTNewHorizons:ForgeMultipart:1.3.4'

runtimeOnlyNonPublishable 'com.github.GTNewHorizons:NotEnoughItems:2.3.57-GTNH:dev'

testImplementation 'org.mockito:mockito-core:5.4.0'
}
2 changes: 2 additions & 0 deletions src/main/java/com/sk89q/jnbt/CompoundTag.java
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,8 @@ public String toString() {
.append(" entries\r\n{\r\n");
for (Map.Entry<String, Tag> entry : value.entrySet()) {
bldr.append(" ")
.append(entry.getKey())
.append(" = ")
.append(
entry.getValue()
.toString()
Expand Down
9 changes: 8 additions & 1 deletion src/main/java/com/sk89q/worldedit/forge/ForgeWorldEdit.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,12 @@
/**
* The Forge implementation of WorldEdit.
*/
@Mod(modid = ForgeWorldEdit.MOD_ID, name = "WorldEdit", version = "%VERSION%", acceptableRemoteVersions = "*")
@Mod(
modid = ForgeWorldEdit.MOD_ID,
name = "WorldEdit",
version = "%VERSION%",
acceptableRemoteVersions = "*",
dependencies = "after:ForgeMultipart;after:ArchitectureCraft")
public class ForgeWorldEdit {

public static Logger logger;
Expand Down Expand Up @@ -97,6 +102,8 @@ public void preInit(FMLPreInitializationEvent event) {

if (Loader.isModLoaded("ForgeMultipart")) {
compat = new ForgeMultipartExistsCompat();
ForgeWorldData.getInstance()
.addBlockTransformHook((ForgeMultipartExistsCompat) compat);
}
if (Loader.isModLoaded("ArchitectureCraft")) {
ForgeWorldData.getInstance()
Expand Down
77 changes: 0 additions & 77 deletions src/main/java/com/sk89q/worldedit/forge/TileEntityUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@

package com.sk89q.worldedit.forge;

import static com.google.common.base.Preconditions.checkNotNull;

import java.lang.reflect.Constructor;

import javax.annotation.Nullable;

import net.minecraft.nbt.NBTTagCompound;
Expand All @@ -44,48 +40,13 @@ private TileEntityUtils() {}
* @return a tag compound
*/
private static NBTTagCompound updateForSet(NBTTagCompound tag, Vector position) {
checkNotNull(tag);
checkNotNull(position);

tag.setTag("x", new NBTTagInt(position.getBlockX()));
tag.setTag("y", new NBTTagInt(position.getBlockY()));
tag.setTag("z", new NBTTagInt(position.getBlockZ()));

return tag;
}

/**
* Set a tile entity at the given location.
*
* @param world the world
* @param position the position
* @param clazz the tile entity class
* @param tag the tag for the tile entity (may be null to not set NBT data)
*/
static void setTileEntity(World world, Vector position, Class<? extends TileEntity> clazz,
@Nullable NBTTagCompound tag) {
checkNotNull(world);
checkNotNull(position);
checkNotNull(clazz);

TileEntity tileEntity = constructTileEntity(world, position, clazz);

if (tileEntity == null) {
return;
}

if (tag != null) {
// Set X, Y, Z
updateForSet(tag, position);
tileEntity.readFromNBT(tag);
}

tileEntity = ForgeWorldEdit.inst.getFMPCompat()
.overrideTileEntity(world, tag, tileEntity);

setTileEntity(world, position, tileEntity);
}

/**
* Set a tile entity at the given location using the tile entity ID from
* the tag.
Expand Down Expand Up @@ -115,42 +76,4 @@ private static void setTileEntity(World world, Vector position, TileEntity tileE
ForgeWorldEdit.inst.getFMPCompat()
.sendDescPacket(world, tileEntity);
}

/**
* Construct a tile entity from the given class.
*
* @param world the world
* @param position the position
* @param clazz the class
* @return a tile entity (may be null if it failed)
*/
@Nullable
static TileEntity constructTileEntity(World world, Vector position, Class<? extends TileEntity> clazz) {
Constructor<? extends TileEntity> baseConstructor;
try {
baseConstructor = clazz.getConstructor(); // creates "blank" TE
} catch (Throwable e) {
return null; // every TE *should* have this constructor, so this isn't necessary
}

TileEntity genericTE;
try {
// Downcast here for return while retaining the type
genericTE = (TileEntity) baseConstructor.newInstance();
} catch (Throwable e) {
return null;
}

/*
* genericTE.blockType = Block.blocksList[block.getId()];
* genericTE.blockMetadata = block.getData();
* genericTE.xCoord = pt.getBlockX();
* genericTE.yCoord = pt.getBlockY();
* genericTE.zCoord = pt.getBlockZ();
* genericTE.worldObj = world;
*/ // handled by internal code

return genericTE;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -109,5 +109,4 @@ private int rotationIndex(byte[] rotations, byte side) {
}
return -1;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,28 @@
*/
package com.sk89q.worldedit.forge.compat;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Nullable;

import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;

import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.CompoundTagBuilder;
import com.sk89q.jnbt.ListTag;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.extent.transform.BlockTransformHook;
import com.sk89q.worldedit.math.transform.AffineTransform;
import com.sk89q.worldedit.math.transform.Transform;

import codechicken.multipart.MultipartHelper;
import codechicken.multipart.TileMultipart;

public class ForgeMultipartExistsCompat implements ForgeMultipartCompat {
public class ForgeMultipartExistsCompat implements ForgeMultipartCompat, BlockTransformHook {

@Override
public TileEntity overrideTileEntity(World world, @Nullable NBTTagCompound tag, TileEntity normal) {
Expand All @@ -43,7 +55,164 @@ public void sendDescPacket(World world, TileEntity entity) {
if (entity instanceof TileMultipart) {
TileMultipart multi = (TileMultipart) entity;
MultipartHelper.sendDescPacket(world, multi);
NBTTagCompound nbt = new NBTTagCompound();
multi.writeToNBT(nbt);
}
}

private int rotateSlot(int[][] edge_rotations, int slot, int ticks) {
for (int type = 0; type < edge_rotations.length; type++) {
int[] rotations = edge_rotations[type];
for (int i = 0; i < rotations.length; i++) {
if (rotations[i] == slot) {
// make sure ticks is positive
ticks = ticks % rotations.length + rotations.length;
slot = rotations[(i + ticks) % rotations.length];
return slot;
}
}
}
return -1;
}

private int[][] edge_rotations = { { 4, 10, 5, 8 }, // bottom edges
{ 6, 11, 7, 9 }, // top edges
{ 2, 0, 1, 3 }, // corner vertical
};

private int rotateEdgeSlot(Vector rot, int slot) {
if (rot.getY() > 0) {
int ticks = (int) Math.round(rot.getY() / 90);
slot = rotateSlot(edge_rotations, slot, ticks);
}
if (rot.getX() < 0) {
int ticks = (int) Math.round(rot.getX() / 90);
System.out.println("X rotation currently unsupported");
}
if (rot.getZ() > 0) {
int ticks = (int) Math.round(rot.getZ() / 90);
System.out.println("Z rotation currently unsupported");
}
return slot;
}

private int[][] post_rotations = { { 0 }, // Y
{ 1 }, // X
{ 2 }, // Z
};

private int rotatePostSlot(Vector rot, int slot) {
if (rot.getY() > 0) {
int ticks = (int) Math.round(rot.getY() / 90);
slot = rotateSlot(post_rotations, slot, ticks);
}
if (rot.getX() < 0) {
int ticks = (int) Math.round(rot.getX() / 90);
System.out.println("X rotation currently unsupported");
}
if (rot.getZ() > 0) {
int ticks = (int) Math.round(rot.getZ() / 90);
System.out.println("Z rotation currently unsupported");
}
return slot;
}

private int[][] cnr_rotations = { { 0, 2, 6, 4 }, // bottom
{ 1, 3, 7, 5 }, // top
};

private int rotateCnrSlot(Vector rot, int slot) {
if (rot.getY() > 0) {
int ticks = (int) Math.round(rot.getY() / 90);
slot = rotateSlot(cnr_rotations, slot, ticks);
}
if (rot.getX() < 0) {
int ticks = (int) Math.round(rot.getX() / 90);
System.out.println("X rotation currently unsupported");
}
if (rot.getZ() > 0) {
int ticks = (int) Math.round(rot.getZ() / 90);
System.out.println("Z rotation currently unsupported");
}
return slot;
}

private int[][] face_rotations = { { 0 }, // bottom
{ 2, 5, 3, 4 }, // edges
{ 1 }, // top
};

private int rotateFaceSlot(Vector rot, int slot) {
if (rot.getY() > 0) {
int ticks = (int) Math.round(rot.getY() / 90);
slot = rotateSlot(face_rotations, slot, ticks);
}
if (rot.getX() < 0) {
int ticks = (int) Math.round(rot.getX() / 90);
System.out.println("X rotation currently unsupported");
}
if (rot.getZ() > 0) {
int ticks = (int) Math.round(rot.getZ() / 90);
System.out.println("Z rotation currently unsupported");
}
return slot;
}

@Override
public BaseBlock transformBlock(BaseBlock block, Transform transform) {
CompoundTag nbt = block.getNbtData();
if (nbt == null) {
return block;
}
if (!"savedMultipart".equals(nbt.getString("id"))) {
return block;
}
if (!(transform instanceof AffineTransform affine)) {
return block;
}
Vector rot = affine.getRotations();
if (rot.lengthSq() == 0) {
return block;
}

CompoundTagBuilder builder = nbt.createBuilder();

List<CompoundTag> parts = new ArrayList<>(nbt.getList("parts", CompoundTag.class));
for (int i = 0; i < parts.size(); i++) {
CompoundTag part = parts.get(i);
String id = part.getString("id");
byte shape = part.getByte("shape");
int size = shape >> 4;
int slot = shape & 0xF;
switch (id) {
case "mcr_edge":
slot = rotateEdgeSlot(rot, slot);
break;

case "mcr_post":
slot = rotatePostSlot(rot, slot);
break;

case "mcr_cnr":
slot = rotateCnrSlot(rot, slot);
break;

case "mcr_face", "mcr_hllw":
slot = rotateFaceSlot(rot, slot);
break;

default:
break;
}
shape = (byte) ((size << 4) | slot);

CompoundTagBuilder partBuilder = part.createBuilder();
partBuilder.putByte("shape", shape);
parts.set(i, partBuilder.build());
}
builder.put("parts", new ListTag(CompoundTag.class, parts));

return new BaseBlock(block.getId(), block.getData(), builder.build());
}

}

0 comments on commit f133ab3

Please sign in to comment.