Jump to content

Sir_Fatal

Members
  • Posts

    4
  • Joined

  • Last visited

Converted

  • Gender
    Male
  • Personal Text
    Adventure Plus [+] modding :P

Sir_Fatal's Achievements

Tree Puncher

Tree Puncher (2/8)

2

Reputation

  1. I cam across the same problem with my tile entitys when coding my mod, the way to get it to sync is to create your own packets. To do this I first created a abstract class called IPacket which all my packet classes will extend; [spoiler=IPacket Class] import net.minecraft.entity.player.EntityPlayer; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; public abstract class IPacket { public abstract void encodeInto(ChannelHandlerContext ctx, ByteBuf buffer); public abstract void decodeInto(ChannelHandlerContext ctx, ByteBuf buffer); public abstract void handleClientSide(EntityPlayer player); public abstract void handleServerSide(EntityPlayer player); } then from this I created a PacketPipeline class that will handle the packets for me [spoiler=PacketPipeline Class] import java.util.*; import com.sirfatal.adventureplus.Network.Packets.*; import com.sirfatal.adventureplus.utils.ModInfo; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.MessageToMessageCodec; import net.minecraft.client.Minecraft; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.network.INetHandler; import net.minecraft.network.NetHandlerPlayServer; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.network.FMLEmbeddedChannel; import cpw.mods.fml.common.network.FMLOutboundHandler; import cpw.mods.fml.common.network.NetworkRegistry; import cpw.mods.fml.common.network.internal.FMLProxyPacket; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; @ChannelHandler.Sharable public class PacketPipeline extends MessageToMessageCodec<FMLProxyPacket, IPacket> { private EnumMap<Side, FMLEmbeddedChannel> channels; private LinkedList<Class<? extends IPacket>> packets = new LinkedList<Class<? extends IPacket>>(); private boolean isPostInitialised = false; /** * Register your packet with the pipeline. Discriminators are automatically * set. * * @param clazz * the class to register * * @return whether registration was successful. Failure may occur if 256 * packets have been registered or if the registry already contains * this packet */ public boolean registerPacket(Class<? extends IPacket> clazz) { if (this.packets.size() > 256) { // You should log here!! return false; } if (this.packets.contains(clazz)) { // You should log here!! return false; } if (this.isPostInitialised) { // You should log here!! return false; } this.packets.add(clazz); return true; } // In line encoding of the packet, including discriminator setting @Override protected void encode(ChannelHandlerContext ctx, IPacket msg, List<Object> out) throws Exception { ByteBuf buffer = Unpooled.buffer(); Class<? extends IPacket> clazz = msg.getClass(); if (!this.packets.contains(msg.getClass())) { throw new NullPointerException("No Packet Registered for: " + msg.getClass().getCanonicalName()); } byte discriminator = (byte) this.packets.indexOf(clazz); buffer.writeByte(discriminator); msg.encodeInto(ctx, buffer); FMLProxyPacket proxyPacket = new FMLProxyPacket(buffer.copy(), ctx.channel() .attr(NetworkRegistry.FML_CHANNEL).get()); out.add(proxyPacket); } // In line decoding and handling of the packet @Override protected void decode(ChannelHandlerContext ctx, FMLProxyPacket msg, List<Object> out) throws Exception { ByteBuf payload = msg.payload(); byte discriminator = payload.readByte(); Class<? extends IPacket> clazz = this.packets.get(discriminator); if (clazz == null) { throw new NullPointerException("No packet registered for discriminator: " + discriminator); } IPacket pkt = clazz.newInstance(); pkt.decodeInto(ctx, payload.slice()); EntityPlayer player; switch (FMLCommonHandler.instance().getEffectiveSide()) { case CLIENT: player = this.getClientPlayer(); pkt.handleClientSide(player); break; case SERVER: INetHandler netHandler = ctx.channel().attr(NetworkRegistry.NET_HANDLER).get(); player = ((NetHandlerPlayServer) netHandler).playerEntity; pkt.handleServerSide(player); break; default: } out.add(pkt); } // Method to call from FMLInitializationEvent public void initialise() { this.channels = NetworkRegistry.INSTANCE.newChannel(ModInfo.CHANNEL, this); registerPackets(); } public void registerPackets() { //registerPacket(PACKETFILENAME.class); } // Method to call from FMLPostInitializationEvent // Ensures that packet discriminators are common between server and client // by using logical sorting public void postInitialise() { if (this.isPostInitialised) { return; } this.isPostInitialised = true; Collections.sort(this.packets, new Comparator<Class<? extends IPacket>>() { @Override public int compare(Class<? extends IPacket> clazz1, Class<? extends IPacket> clazz2) { int com = String.CASE_INSENSITIVE_ORDER.compare(clazz1.getCanonicalName(), clazz2.getCanonicalName()); if (com == 0) { com = clazz1.getCanonicalName().compareTo(clazz2.getCanonicalName()); } return com; } }); } @SideOnly(Side.CLIENT) private EntityPlayer getClientPlayer() { return Minecraft.getMinecraft().thePlayer; } /** * Send this message to everyone. * <p/> * Adapted from CPW's code in * cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper * * @param message * The message to send */ public void sendToAll(IPacket message) { this.channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET) .set(FMLOutboundHandler.OutboundTarget.ALL); this.channels.get(Side.SERVER).writeAndFlush(message); } /** * Send this message to the specified player. * <p/> * Adapted from CPW's code in * cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper * * @param message * The message to send * @param player * The player to send it to */ public void sendTo(IPacket message, EntityPlayerMP player) { this.channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET) .set(FMLOutboundHandler.OutboundTarget.PLAYER); this.channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(player); this.channels.get(Side.SERVER).writeAndFlush(message); } /** * Send this message to everyone within a certain range of a point. * <p/> * Adapted from CPW's code in * cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper * * @param message * The message to send * @param point * The * {@link cpw.mods.fml.common.network.NetworkRegistry.TargetPoint} * around which to send */ public void sendToAllAround(IPacket message, NetworkRegistry.TargetPoint point) { this.channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET) .set(FMLOutboundHandler.OutboundTarget.ALLAROUNDPOINT); this.channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(point); this.channels.get(Side.SERVER).writeAndFlush(message); } /** * Send this message to everyone within the supplied dimension. * <p/> * Adapted from CPW's code in * cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper * * @param message * The message to send * @param dimensionId * The dimension id to target */ public void sendToDimension(IPacket message, int dimensionId) { this.channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGET) .set(FMLOutboundHandler.OutboundTarget.DIMENSION); this.channels.get(Side.SERVER).attr(FMLOutboundHandler.FML_MESSAGETARGETARGS) .set(dimensionId); this.channels.get(Side.SERVER).writeAndFlush(message); } /** * Send this message to the server. * <p/> * Adapted from CPW's code in * cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper * * @param message * The message to send */ public void sendToServer(IPacket message) { this.channels.get(Side.CLIENT).attr(FMLOutboundHandler.FML_MESSAGETARGET) .set(FMLOutboundHandler.OutboundTarget.TOSERVER); this.channels.get(Side.CLIENT).writeAndFlush(message); } } In the register packet function you will want to put all the packets you want to register for example registerPacket(PacketUpdateTE.class); Next you want to setup your packet class for that tileentity, it will take in 3 parameters and also any other parameters you want to set, for example valueToSet can be whatever you want just make sure you register all your packet classes inside the packetpipeline. [spoiler=Packet TileEntity Class] import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; public class PacketTileTE extends IPacket { int xPos, yPos, zPos, dimension; int valueToSet; public PacketTileTE() { } public PacketTileTE(int dimension, int xPos, int yPos, int zPos, int valueToSet) { this.dimension = dimension; this.xPos = xPos; this.yPos = yPos; this.zPos = zPos; this.valueToSet = valueToSet; } @Override public void encodeInto(ChannelHandlerContext ctx, ByteBuf buffer) { buffer.writeInt(xPos); buffer.writeInt(yPos); buffer.writeInt(zPos); buffer.writeInt(valueToSet); } @Override public void decodeInto(ChannelHandlerContext ctx, ByteBuf buffer) { xPos = buffer.readInt(); yPos = buffer.readInt(); zPos = buffer.readInt(); x = buffer.readInt(); } @Override public void handleClientSide(EntityPlayer player) { } @Override public void handleServerSide(EntityPlayer player) { World world = player.worldObj; TileEntity te = world.getTileEntity(xPos, yPos, zPos); if (te instanceof TILE) { NBTTagCompound data = new NBTTagCompound(); ((YOURTileEntity) te).setVALUE(valueToSet); ((eventTileEntity) te).writeToNBT(data); packetPipeline.sendToAll(new PacketUpdateTE(xPos, yPos, zPos, data)); } } } The last class you will want to make is the PacketUpdateTE. This will just update you tile entity on the client side and can be used by multiple packet tile entity classes. [spoiler=PacketUpdateTE] import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.PacketBuffer; import net.minecraft.tileentity.TileEntity; import com.sirfatal.adventureplus.Network.IPacket; public class PacketUpdateTE extends IPacket { private int xPos, yPos, zPos; private NBTTagCompound data; public PacketUpdateTE() { } public PacketUpdateTE(int xPos, int yPos, int zPos, NBTTagCompound data) { this.xPos = xPos; this.yPos = yPos; this.zPos = zPos; this.data = data; } @Override public void encodeInto(ChannelHandlerContext ctx, ByteBuf buffer) { PacketBuffer pckBuff = new PacketBuffer(buffer); pckBuff.writeInt(xPos); pckBuff.writeShort(yPos); pckBuff.writeInt(zPos); try { pckBuff.writeNBTTagCompoundToBuffer(data); } catch (Exception e) { e.printStackTrace(); } } @Override public void decodeInto(ChannelHandlerContext ctx, ByteBuf buffer) { PacketBuffer pckBuff = new PacketBuffer(buffer); xPos = pckBuff.readInt(); yPos = pckBuff.readShort(); zPos = pckBuff.readInt(); try { data = pckBuff.readNBTTagCompoundFromBuffer(); } catch (Exception e) { e.printStackTrace(); } } @Override public void handleClientSide(EntityPlayer player) { TileEntity te = player.worldObj.getTileEntity(xPos, yPos, zPos); if (te != null) { te.readFromNBT(data); } } @Override public void handleServerSide(EntityPlayer player) { } } The final things you want to do is in your main mod class initialise the packet pipeline public static final PacketPipeline packetPipeline = new PacketPipeline(); @EventHandler public void initialise(FMLInitializationEvent evt) { packetPipeline.initialise(); } @EventHandler public void postInitialise(FMLPostInitializationEvent evt) { packetPipeline.postInitialise(); } And also in your entity class where you want the sync to happen put packetPipeline.sendToServer(new PacketENTITYTE( this.worldObj.provider.dimensionId, this.xCoord, this.yCoord, this.zCoord, VALUE)); If you want some more help just ask and also all this information can be found in the Netty Packet Tutorial on the forums HERE -SirFatal
  2. Adventure Plus allows map creators add more to their maps for others to play to both enhance their users experience but also provide easy tools to do so. With Adventure Plus, it adds new items to the game such as event blocks and trigger blocks at the current stage of development. Event Block The Event block is the main block within the mod that controls all the events that can be done in the mod at the moment with more blocks to follow. [spoiler=Event Block] [spoiler=Event GUI] With the event gui, the user is able to select a starting X, Y and Z position for the event to be triggered then specify the width, height and depth from that position for the triggers to fill. From this menu as well the user can select whether or not to output a red stone signal to the surrounding blocks for when the event block is triggered. <p>They will also be able to; Summon mobs that the user may have to kill to get a drop to proceed on with the map Do varies effects to the player such as teleport Set blocks, replace blocks or delete blocks from a given area Apply different effects to the surroundings [spoiler=Mob Tab] Currently a work in progress tab which will house all the mob events that the user sets up. The slider at the side has all the mobs that are initialised within the running forge client. Trigger Block The trigger block is the block that when interacted with the player, triggers the event block that the trigger block is associated with. [spoiler=Trigger Block] [spoiler=Trigger GUI] With the trigger gui, the user is able to see the event blocks position that it is linked with and also select if they want to output a redstone signal when a player interacts with the block. Also in the corner of the GUI is a green / red indicator that checks to see if the coordinates of the event block position is true and if it is, shows a green indicator else it will be red. Helper Item The helper item, helps the creator map out a given area within the world so that they can easily input the values into the eventBlock easier. [spoiler=Helper Item] [spoiler=Helper GUI] Change Log [spoiler=Change Log] [spoiler=0.6.2] Basic outline of the mob spawn event started. Fixed bug where 2 instances of a mob would spawn. [spoiler=0.5.5] Added function to allow for other mobs from other mods to be added to the event. Helper Item so the user can easily enter trigger coordinates Feedback would be much appreciated as well as any ideas you would like to be added / modified in the mod. Source code can be found on github Minecraft forums post can be found here -SirFatal
  3. Thanks GreyGhost, I already solved it with roughly that method of doing it and when it bindstexture I just called the function private ResourceLocation checkGameMode() { if (Minecraft.getMinecraft().playerController.isNotCreative()) { return new ResourceLocation(ModInfo.MODID, "textures/blocks/invBlock.png"); } else { return new ResourceLocation(ModInfo.MODID, "textures/blocks/triggerBlock.png"); } }
  4. Is it possible to have it so that if the player is in creative mode then the block is displayed with a texture and then if they are not in creative mode, then the block would be still there but transparent?
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.