Skip to content

Instantly share code, notes, and snippets.

@tterrag1098
Last active August 27, 2015 12:42
Show Gist options
  • Save tterrag1098/d94969121382b4afaffb to your computer and use it in GitHub Desktop.
Save tterrag1098/d94969121382b4afaffb to your computer and use it in GitHub Desktop.
V* SHIFTING :D
package team.chisel.item;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import team.chisel.api.ChiselTabs;
import team.chisel.api.ICarvable;
import team.chisel.api.rendering.TextureType;
import team.chisel.utils.NBTSaveable;
import team.chisel.utils.PerChunkData;
import team.chisel.utils.PerChunkData.ChunkDataBase;
import com.google.common.collect.Lists;
public class ItemOffsetTool extends Item {
public static class OffsetData implements NBTSaveable {
private int xOffset, yOffset, zOffset;
@Override
public void write(NBTTagCompound tag) {
tag.setShort("offset", (short) (xOffset << 8 | yOffset << 4 | zOffset));
}
@Override
public void read(NBTTagCompound tag) {
short offset = tag.getShort("offset");
xOffset = (offset >> 8) & 0xF;
yOffset = (offset >> 4) & 0xF;
zOffset = offset & 0xF;
}
public void move(ForgeDirection dir) {
if (dir.offsetX != 0) {
xOffset = updateValue(xOffset, dir.offsetX);
} else if (dir.offsetY != 0) {
yOffset = updateValue(yOffset, dir.offsetY);
} else {
zOffset = updateValue(zOffset, dir.offsetZ);
}
}
public int getOffsetX() {
return xOffset;
}
public int getOffsetY() {
return yOffset;
}
public int getOffsetZ() {
return zOffset;
}
private int updateValue(int current, int move) {
current += move;
current %= 16;
if (current < 0) {
current += 16;
}
return current;
}
}
public static final String DATA_KEY = "offsettool";
private static final List<TextureType> validTypes = Lists.newArrayList(TextureType.V4, TextureType.V9 /*SOON, TextureType.V16 */);
public ItemOffsetTool() {
super();
setCreativeTab(ChiselTabs.tabChisel);
setUnlocalizedName("chisel.offsettool");
setTextureName("offsettool");
PerChunkData.INSTANCE.registerChunkData(DATA_KEY, new ChunkDataBase<OffsetData>(OffsetData.class, true));
}
@Override
public boolean onItemUse(ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side, float hitX, float hitY, float hitZ) {
Block block = world.getBlock(x, y, z);
if (block instanceof ICarvable) {
if (world.isRemote) {
ICarvable carvable = (ICarvable) block;
if (validTypes.contains(carvable.getManager(world.getBlockMetadata(x, y, z)).getType())) {
return true;
}
return false;
} else {
ChunkDataBase<OffsetData> cd = PerChunkData.INSTANCE.getData(DATA_KEY);
OffsetData data = cd.getDataForChunk(world.getChunkFromBlockCoords(x, z));
ForgeDirection face = ForgeDirection.getOrientation(side);
data.move(player.isSneaking() ? face.getOpposite() : face);
PerChunkData.INSTANCE.chunkModified(world.getChunkFromBlockCoords(x, z), DATA_KEY);
System.out.println(data.xOffset + " " + data.yOffset + " " + data.zOffset);
}
}
return super.onItemUse(stack, player, world, x, y, z, side, hitX, hitY, hitZ);
}
}
package team.chisel.utils;
import io.netty.buffer.ByteBuf;
import java.util.Map;
import java.util.Map.Entry;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.ChunkCoordIntPair;
import net.minecraft.world.chunk.Chunk;
import net.minecraftforge.event.world.ChunkDataEvent;
import team.chisel.Chisel;
import team.chisel.network.PacketHandler;
import com.google.common.collect.Maps;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.common.network.ByteBufUtils;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
public enum PerChunkData {
INSTANCE;
public static class MessageChunkData implements IMessage {
private ChunkCoordIntPair chunk;
private String key;
private NBTTagCompound tag;
public MessageChunkData() {
}
public MessageChunkData(Chunk chunk, String key, NBTTagCompound tag) {
this.chunk = chunk.getChunkCoordIntPair();
this.key = key;
this.tag = tag;
}
@Override
public void toBytes(ByteBuf buf) {
buf.writeInt(chunk.chunkXPos);
buf.writeInt(chunk.chunkZPos);
ByteBufUtils.writeUTF8String(buf, key);
ByteBufUtils.writeTag(buf, tag);
}
@Override
public void fromBytes(ByteBuf buf) {
this.chunk = new ChunkCoordIntPair(buf.readInt(), buf.readInt());
this.key = ByteBufUtils.readUTF8String(buf);
this.tag = ByteBufUtils.readTag(buf);
}
}
public static class MessageChunkDataHandler implements IMessageHandler<MessageChunkData, IMessage> {
@Override
public IMessage onMessage(MessageChunkData message, MessageContext ctx) {
Chunk chunk = Chisel.proxy.getClientWorld().getChunkFromChunkCoords(message.chunk.chunkXPos, message.chunk.chunkZPos);
IChunkData data = INSTANCE.data.get(message.key);
data.readFromNBT(chunk, message.tag);
int x = chunk.xPosition << 4;
int z = chunk.zPosition << 4;
Chisel.proxy.getClientWorld().markBlockRangeForRenderUpdate(x, 0, z, x, 255, z);
return null;
}
}
public interface IChunkData {
void writeToNBT(Chunk chunk, NBTTagCompound tag);
void readFromNBT(Chunk chunk, NBTTagCompound tag);
boolean requiresClientSync();
}
/**
* @param <T>
* MUST have a default constructor.
*/
public static class ChunkDataBase<T extends NBTSaveable> implements IChunkData {
protected final Map<ChunkCoordIntPair, T> data = Maps.newHashMap();
protected final Class<? extends T> clazz;
private final boolean needsClientSync;
public ChunkDataBase(Class<? extends T> clazz, boolean needsClientSync) {
this.clazz = clazz;
this.needsClientSync = needsClientSync;
}
@Override
public void writeToNBT(Chunk chunk, NBTTagCompound tag) {
T t = data.get(chunk.getChunkCoordIntPair());
if (t != null) {
t.write(tag);
}
}
@Override
public void readFromNBT(Chunk chunk, NBTTagCompound tag) {
ChunkCoordIntPair coords = chunk.getChunkCoordIntPair();
if (tag.hasNoTags()) {
data.remove(coords);
return;
}
T t = getOrCreateNew(coords);
t.read(tag);
}
protected T getOrCreateNew(ChunkCoordIntPair coords) {
T t = data.get(coords);
if (t == null) {
try {
t = clazz.newInstance();
} catch (Exception e) {
Chisel.logger.error("Could not instantiate NBTSaveable " + clazz.getName() + "!");
e.printStackTrace();
}
}
data.put(coords, t);
return t;
}
@Override
public boolean requiresClientSync() {
return needsClientSync;
}
public T getDataForChunk(Chunk chunk) {
return getDataForChunk(chunk.getChunkCoordIntPair());
}
public T getDataForChunk(ChunkCoordIntPair coords) {
return getOrCreateNew(coords);
}
}
private Map<String, IChunkData> data = Maps.newHashMap();
public void registerChunkData(String key, IChunkData cd) {
data.put(key, cd);
}
@SuppressWarnings("unchecked")
public <T extends IChunkData> T getData(String key) {
return (T) data.get(key);
}
@SubscribeEvent
public void onChunkSave(ChunkDataEvent.Save event) {
for (Entry<String, IChunkData> e : data.entrySet()) {
NBTTagCompound tag = new NBTTagCompound();
e.getValue().writeToNBT(event.getChunk(), tag);
event.getData().setTag("chisel:" + e.getKey(), tag);
}
}
@SubscribeEvent
public void onChunkLoad(ChunkDataEvent.Load event) {
for (Entry<String, IChunkData> e : data.entrySet()) {
NBTTagCompound tag = event.getData().getCompoundTag("chisel:" + e.getKey());
e.getValue().readFromNBT(event.getChunk(), tag);
}
}
public void chunkModified(Chunk chunk, String key) {
IChunkData cd = data.get(key);
if (cd.requiresClientSync()) {
NBTTagCompound tag = new NBTTagCompound();
cd.writeToNBT(chunk, tag);
PacketHandler.INSTANCE.sendToAll(new MessageChunkData(chunk, key, tag));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment