Jump to content

Major Squirrel

Members
  • Posts

    117
  • Joined

  • Last visited

Everything posted by Major Squirrel

  1. Good evening, According to some modders on Discord, the only way to use 22.5° degrees rotations properly in blockstates files would be to use OBJ models. Another solution would be to create 4 models with different rotations and to handle 4 different states per model in blockstates files so that it would handle the 16 rotations (see also this topic). Thank you for helping me !
  2. https://minecraft.gamepedia.com/Model#Block_states This is why I use the Forge blockstate format, with Forge marker set as 1. Well this is exactly what I did in my blockstates file : { "forge_marker": 1, "defaults": { "model": "mymod:standing_rp_sign", "uvlock": true }, "variants": { "rotation": { "0": { "transform": { "rotation": { "y": 180 } } }, "1": { "transform": { "rotation": { "y": 157.5 } } }, "2": { "transform": { "rotation": { "y": 135 } } }, "3": { "transform": { "rotation": { "y": 112.5 } } }, "4": { "transform": { "rotation": { "y": 90 } } }, "5": { "transform": { "rotation": { "y": 67.5 } } }, "6": { "transform": { "rotation": { "y": 45 } } }, "7": { "transform": { "rotation": { "y": 22.5 } } }, "8": { "transform": { "rotation": { "y": 0 } } }, "9": { "transform": { "rotation": { "y": 337.5 } } }, "10": { "transform": { "rotation": { "y": 315 } } }, "11": { "transform": { "rotation": { "y": 292.5 } } }, "12": { "transform": { "rotation": { "y": 270 } } }, "13": { "transform": { "rotation": { "y": 247.5 } } }, "14": { "transform": { "rotation": { "y": 225 } } }, "15": { "transform": { "rotation": { "y": 202.5 } } } } } } Following output :
  3. Well I don’t understand the behavior shown on my screenshot above. Did I do something wrong in my blockstate file ? I can’t figure out.
  4. I don't want to render any text on the sign, that is why I would like to avoid using TESR. According to @diesieben07 in the link I've posted above, the TRSRTransformation rotation can achieve 22.5 degrees increments, that's why I don't really understand.
  5. Thank you @desht, I will give a try. Also, I'm trying to avoid using TESR by only using Forge Blockstate format. For the wall sign it is pretty easy as Vanilla blockstate increments rotation every 90 degrees, but for the standing sign it is a little bit more complicated as it has 16 possible rotations. I've read this post where it is advised to use the Forge Blockstate V1 specs available here but I guess I have difficulties in understanding the specs. Here is what I got : The original model for the block (the uniform face is purposely complete beige so I could see where it faces) : (blockstates/standing_rp_sign.json) (block/standing_rp_sign.json) I don't really understand what is going on here tbh.
  6. The purpose would be to display data stored in the TileEntity, inside a GUI. Then, I guess I would call the server to retrieve the data and to pass it to the GUI ?
  7. (BlockRPSign.java) It works with the code above, I was overriding the wrong hasTileEntity method (the one without any parameter) , thank you. Could you please explain a little more about why you indicate me to use a proxy ? I know this part of code is executed on the server thread and I'm calling clientside code with Minecraft#displayGuiScreen, but I don't find a way to open a GUI remotely of a TileEntity without any Container. EDIT: is it as simple as using a GuiHandler and returning null in getServerGuiElement ...?
  8. I've added "empty" blockstate files and model files like so : (blockstates/standing_rp_sign.json) (blockstates/wall_rp_sign.json) (models/block/standing_rp_sign.json and models/block/wall_rp_sign.json) It does fix all MissingVariant exceptions as well as emitted particles when signs are destroyed. However, when changing my BlockRPSign from BlockContainer to Block with Block#hasTileEntity and Block#createTileEntity overriden, the render() method from the TESR is not called anymore. Instead, I've made my class extend to Block, implementing ITileEntityProvider. It works now. What do you mean by proxy ? Sending a packet to the server and the server opens a player GUI ?
  9. Good evening, Thank you @V0idWa1k3r for your answer. I couldn't find it in Vanilla code earlier. Is it in the BlockModelShapes#registerAllBlocks method ? I guess I will have to create an "empty" blockstates file if I want to override emitted particles anyway. Isn't this method supposed to be used when there is a Container attached to the TileEntity ? My TileEntity has no Container, it just has some data stored (TextComponents) in it. For what is left, I simply copied/pasted Vanilla code. Now I've fixed the useless casts, boxing/unboxing, arrays, etc... Thank you for that.
  10. Good evening, I'm modding a custom sign which is translucent and smaller than the Vanilla's one. I've looked for Vanilla classes to mimic the existing BlockSign and its children BlockStandingSign and BlockWallSign. I've also made a custom TileEntitySpecialRenderer and registered it. (BlockRPSign.java) (BlockStandingRPSign.java) (BlockWallRPSign.java) (ItemRPSign.java) (TileEntityRPSignRenderer.java) (MyModBlocks.java) (MyModItems.java) (MyModTileEntities.java) (As you may see, I'm using @jabelar mod structure from the GitHub repo here) I'm getting a net.minecraft.client.renderer.block.model.ModelBlockDefinition$MissingVariantException for my standing_rp_sign blockstate with rotation variants. I haven't created any blockstate file for both standing and wall signs since there is an existing TESR which handles the rendering. I've tried to look for a model loading from Vanilla's sign but I didn't find anything. My guess would be to indicate Forge to avoid handling models for those blocks but i don't know how to do that. Also, since there is no blockstate and no model attached to the blocks, there are random particles emitted when breaking the block. Vanilla sign has woods particles but I can't see any code or model file that indicates the texture to use for particles from Vanilla. Finally, as you can see in the TESR I'm trying to check the block type from the tileentity (this is done in Vanilla using Block#getBlockType which returns a Block). Is there a better way to do it ? Thank you for your help.
  11. Good evening, So as @Cadiboo stated above, I've been trying to avoid using an entity to render something above players head. The idea would be to send a CPacketPlayerTyping packet from the player typing to the server, then the server sends a SPacketNotifyTyping to every player around to render the indicator. (CPacketPlayerTyping.java) (SPacketNotifyTyping.java) (CustomGuiChat.java) (MyModMenu.java) I don't know what to do next in the onMessage function of the SPacketNotifyTyping packet. I've tried to call Gl functions but it is not in an OpenGL context. Also, I'm wondering if this is a good idea to send a packet on every screen update, what do you think ?
  12. I've updated the tracker accordingly, thank you. ? For now, it seems that it is working as intended (see screenshot below). I've tested it in singleplayer mode and I will test it in multiplayer mode later this day. You're right, I really don't need an entity. What I don't understand with your method is what should I do - on client side - after sending packets from server to client.
  13. My bad, I've created a new instance of EntityChatIndicator but completely forgot to spawn it in the world. The following code works : (ChatIndicatorMessage.java) @Override public IMessage onMessage(ChatIndicatorMessage message, MessageContext ctx) { EntityPlayerMP serverPlayer = ctx.getServerHandler().player; switch (message.messageType) { case 0: { serverPlayer.getServerWorld().addScheduledTask(() -> { Integer indicatorUniqueId = CHAT_INDICATORS.get(serverPlayer.getUniqueID()); if (indicatorUniqueId != null) { EntityChatIndicator chatIndicator = (EntityChatIndicator) serverPlayer.world.getEntityByID(indicatorUniqueId); if (chatIndicator != null) { chatIndicator.setDead(); CHAT_INDICATORS.remove(serverPlayer.getUniqueID()); } } }); break; } case 1: { serverPlayer.getServerWorld().addScheduledTask(() -> { EntityChatIndicator chatIndicator = new EntityChatIndicator(serverPlayer.world, serverPlayer.posX, serverPlayer.posY + 0.5D, serverPlayer.posZ); if (serverPlayer.world.spawnEntity(chatIndicator)) CHAT_INDICATORS.put(serverPlayer.getUniqueID(), chatIndicator.getEntityId()); }); break; } default: break; } return null; } I also modified updateFrequency from 0 to 20 because it causes a "/ by zero" exception. Now, entity updates functions are correctly called but still the doRender function is not called. Any guess ?
  14. Good evening, I've decided to go through an Entity for now, meaning that when a player opens a GuiChat, it sends a packet to the server and the server spawns an Entity with a custom Renderer to render the chat indicator above players head. Here is what I did so far : (ClientProxy.java) public class ClientProxy extends CommonProxy { @Override public void preInit() { super.preInit(); RenderingRegistry.registerEntityRenderingHandler(EntityChatIndicator.class, RenderFactoryEntityChatIndicator.INSTANCE); } @Override public void init() { super.init(); MinecraftForge.EVENT_BUS.register(this); MinecraftForge.EVENT_BUS.register(new EntityEventHandler()); } @SubscribeEvent public void onOpenGui(GuiOpenEvent event) { if (event.getGui() != null) { if (event.getGui().getClass() == GuiChat.class) { event.setGui(new CustomGuiChat()); } } } } (CustomGuiChat.java) public class CustomGuiChat extends GuiChat { @Override public void initGui() { super.initGui(); MyModMenuPacketHandler.INSTANCE.sendToServer(new ChatIndicatorMessage(1)); } @Override public void onGuiClosed() { super.onGuiClosed(); MyModMenuPacketHandler.INSTANCE.sendToServer(new ChatIndicatorMessage(0)); } } (EntityEventHandler.java) @Mod.EventBusSubscriber(modid = MyModMenu.MODID) public final class EntityEventHandler { @SubscribeEvent public static void onEntityConstructing(EntityEvent.EntityConstructing event) { if (event.getEntity() instanceof EntityChatIndicator) { System.out.println("EntityChatIndicator is being constructed !"); } } @SubscribeEvent public static void onEntityRegistering(final RegistryEvent.Register<EntityEntry> event) { System.out.println("Registering entities..."); event.getRegistry().register(EntityEntryBuilder.create() .entity(EntityChatIndicator.class) .id(new ResourceLocation(MyModMenu.MODID, "chat_indicator"), 0) .name("chat_indicator") .tracker(0, 0, false) .build() ); } } (EntityChatIndicator.java) public class EntityChatIndicator extends Entity { public EntityChatIndicator(World worldIn) { this(worldIn, 0.0D, 0.0D, 0.0D); } public EntityChatIndicator(World worldIn, double posX, double posY, double posZ) { super(worldIn); this.setSize(1.0F, 1.0F); this.posX = posX; this.posY = posY; this.posZ = posZ; } @Override protected void entityInit() { } @Override public void onEntityUpdate() { super.onEntityUpdate(); System.out.println("EntityChatIndicator position : (" + this.posX + ", " + this.posY + ", " + this.posZ + ") !"); } @Override public void onUpdate() { super.onUpdate(); System.out.println("EntityChatIndicator position : (" + this.posX + ", " + this.posY + ", " + this.posZ + ") !"); } @Override protected void readEntityFromNBT(NBTTagCompound compound) {} @Override protected void writeEntityToNBT(NBTTagCompound compound) {} } (RenderChatIndicator.java) @SideOnly(Side.CLIENT) public final class RenderChatIndicator extends Render<EntityChatIndicator> { public RenderChatIndicator(RenderManager renderManager) { super(renderManager); } @Override public void doRender(EntityChatIndicator entity, double x, double y, double z, float entityYaw, float partialTicks) { System.out.println("Rendering EntityChatIndicator !"); ItemStack itemstack = new ItemStack(Items.PAPER, 1); if (!itemstack.isEmpty()) { GlStateManager.pushMatrix(); GlStateManager.translate(x, y, z); GlStateManager.rotate(-this.renderManager.playerViewY, 0, 1, 0); GlStateManager.rotate(this.renderManager.playerViewX, 1, 0, 0); GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); Minecraft.getMinecraft().getRenderItem().renderItem(itemstack, ItemCameraTransforms.TransformType.GROUND); GlStateManager.popMatrix(); } super.doRender(entity, x, y, z, entityYaw, partialTicks); } @Nullable @Override protected ResourceLocation getEntityTexture(EntityChatIndicator entity) { return (null); } } (RenderFactoryChatIndicator.java) public class RenderFactoryEntityChatIndicator implements IRenderFactory<EntityChatIndicator> { public static final RenderFactoryEntityChatIndicator INSTANCE = new RenderFactoryEntityChatIndicator(); @Override public Render<EntityChatIndicator> createRenderFor(RenderManager manager) { return (new RenderChatIndicator(manager)); } } (MyModMenuPacketHandler.java) public final class MyModMenuPacketHandler { public static final SimpleNetworkWrapper INSTANCE = NetworkRegistry.INSTANCE.newSimpleChannel(MyModMenu.MODID); private static int discriminator = 0; public static <REQ extends IMessage, REPLY extends IMessage> void registerPacket(Class<? extends IMessageHandler<REQ, REPLY>> messageHandler, Class<REQ> message, Side side) { INSTANCE.registerMessage(messageHandler, message, MyModMenuPacketHandler.discriminator++, side); } } (ChatIndicatorMessage.java) public final class ChatIndicatorMessage implements IMessage { /** * First UUID key is player's UUID * Second Integer value is indicator's UUID */ public static final Map<UUID, Integer> CHAT_INDICATORS = new HashMap<>(); public ChatIndicatorMessage() {} /** * 0 is to DESTROY a chat indicator * 1 is to CREATE a chat indicator */ private int messageType; public ChatIndicatorMessage(int messageType) { this.messageType = messageType; } @Override public void fromBytes(ByteBuf buf) { this.messageType = buf.readInt(); } @Override public void toBytes(ByteBuf buf) { buf.writeInt(this.messageType); } public static final class ChatIndicatorMessageHandler implements IMessageHandler<ChatIndicatorMessage, IMessage> { @Override public IMessage onMessage(ChatIndicatorMessage message, MessageContext ctx) { EntityPlayerMP serverPlayer = ctx.getServerHandler().player; switch (message.messageType) { case 0: { serverPlayer.getServerWorld().addScheduledTask(() -> { Integer indicatorUniqueId = CHAT_INDICATORS.get(serverPlayer.getUniqueID()); if (indicatorUniqueId != null) { EntityChatIndicator chatIndicator = (EntityChatIndicator) serverPlayer.world.getEntityByID(indicatorUniqueId); if (chatIndicator != null) { chatIndicator.setDead(); CHAT_INDICATORS.remove(serverPlayer.getUniqueID()); } } }); break; } case 1: { serverPlayer.getServerWorld().addScheduledTask(() -> { EntityChatIndicator chatIndicator = new EntityChatIndicator(serverPlayer.world, serverPlayer.posX, serverPlayer.posY + 0.5D, serverPlayer.posZ); CHAT_INDICATORS.put(serverPlayer.getUniqueID(), chatIndicator.getEntityId()); }); break; } default: break; } return null; } } } (MyModMenu.java) @Mod(modid = MyModMenu.MODID, version = MyModMenu.VERSION) public class MyModMenu { public static final String MODID = "mymodmenu"; public static final String VERSION = "1.0.0"; @Mod.Instance public static MyModMenu instance; public static Logger logger; @SidedProxy(clientSide = "net.theviolentsquirrels.proxy.ClientProxy", serverSide = "net.theviolentsquirrels.proxy.ServerProxy") public static CommonProxy proxy; @EventHandler public void preInit(FMLPreInitializationEvent event) { MyModMenu.logger = event.getModLog(); MyModMenu.proxy.preInit(); MyModMenuPacketHandler.registerPacket(ChatIndicatorMessage.ChatIndicatorMessageHandler.class, ChatIndicatorMessage.class, Side.SERVER); } @EventHandler public void init(FMLInitializationEvent event) { MyModMenu.proxy.init(); } @EventHandler public void postInit(FMLPostInitializationEvent event) { } } So when I'm opening a GuiChat, it correctly prints out that a packet has been sent to the server. Also, it creates a new EntityChatIndicator (caught in the EntityConstructing event). However, the doRender function and the entity updates functions do not seem to be called at all (no print at least). What I've checked is : The packet is correctly registered The custom renderer seems to be correctly registered with the factory way The entity seems to be correctly registered with the recent builder I don't understand what is going on, maybe you could help me ? EDIT: is it because my EntityChatIndicator is simply an Entity, and not an EntityLiving ? Can a simple Entity be updated ?
  15. Good evening, I'm trying to develop a mod which renders a 2D texture above players to indicate other players that they're typing something in chat. AFAIK I would have to override the GuiChat to handle chat opening, update and chat closing & I would have to do something about rendering (I'm inspired by the way tags work above entities, is it the right way ?). I'm kind of confused right now because this is a client side part and I don't know how could I handle it to every player around the person typing in chat. Are packets the way to go ? Thank you for your replies.
  16. I have tried your function and the event had a lootingLevel value of 21. The context I tested it was killing a polar bear with a diamond sword (no enchants), it dropped me 12 fish. In which context have you tested your event ?
  17. Shouldn't your handle function be static ? public static void HandleEnchant(final LootingLevelEvent event); Also, I suggest your event would be final. --- EDIT: my bad, I didn't see your handle function was properly called.
  18. How many models do you have in your models folder ? What are they ? From the fml-client-latest.log file, your main error seems to be : I suppose that either there is no such model file or there is a problem from registering block models.
  19. [UPDATE] I found out that there is the Forge event RenderSpecificHandEvent which is called for each hand (MAIN_HAND and OFF_HAND). I ended up subscribing to it and making my own rendering functions, based on the ItemRenderer class. Functions that I simply copy-pasted are renderItemInFirstPerson and renderMapFirstPerson. I find it a bit "dirty" that there is a conditional branching only to render an ItemMap inside the rendering pass of Minecraft. Also, certain rendering functions such as renderArms are private and thus could not be overriden or properly called : I have to copy-paste those functions to simulate the same behavior. Do you think it would be possible create a specific event for the map rendering, considering its unique condition in the code ? What do you think ?
  20. Good evening everyone, I am working on a custom map item (original MC is ItemEmptyMap and ItemMap which inherit from ItemMapBase), the purpose is to act the same way as the original one except that I would like some information rendered on it. Also, I would like it to be an item apart but I basically make my item inherit from ItemMap. The part I am struggling with is rendering the map in player's hand and in an item frame. From what I observe in the code, the concerned renderer is the ItemRenderer which renders instances of ItemMap and also MapItemRenderer which renders icons and decorations. Is there any way to affect a specific ItemRenderer for my custom map or an event that could catch the rendering and to play with ? Regards.
  21. Could you please share the code using the code feature ?
  22. Could you provide a sample screen of what kind of GUIs you're talking about ? I might be interested in it ! Personally, I just recycle some existing GUIs from Minecraft. For instance, there is the demo_background.png located in the Minecraft assets (textures/gui). It helps me to prototype a canvas for a beginning. Still, I am really curious of how do other developers achieve their GUIs (especially when we are not specialized designers haha).
  23. [SOLVED] Okay my bad, I just found out that debug messages aren't displayed in the default Console. Higher levels (such as info) are displayed correctly !
  24. It is already displayed so : [11:58:59] [main/DEBUG] [FML/]: Overriding dimension: using 0 [11:59:04] [main/DEBUG] [questly/]: QuestBlock has received a right-click ! (This is the content from fml-client-latest.log) Normally, a log message is displayed into the default IntelliJ Console window but for some reason it doesn't happen. (The Console window is the default one from IntelliJ, the "fml-client-latest" one has been created by me, from the fml-client-latest.log file) Contents from each console is different : I don't understand what is going on, to be honest. Why are my log messages not displayed into the default Console ?
  25. Good evening, Has anyone achieved to log their mod log messages into IntelliJ default Console when running/debugging Minecraft Client/Server ? My log messages are well written into the fml-client-latest.log file and I can create a new IntelliJ Log channel to display my log messages but I would like them to be into the default console. public static final Logger logger = LogManager.getLogger(Questly.MODID); Can anyone help me on this one ? Thanks for you help !
×
×
  • Create New...

Important Information

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