prujohn Posted July 1, 2014 Posted July 1, 2014 Thanks to some excellent help from this community, I've been able to write a mod that spawns little Steve's whenever I like and also allows me to rename them with name tags. I was able to override the "setCustomNameTag()" method of my NPC entity, which is properly called whenever I use a nametag on it. Wanted to check and see if anyone had experience with this? I saw some code in minecraft's AbstractClientPlayer class that performs a download of a player skin, but it seems narrowly focused on skinning the player during construction. Still, some of the plumbing is there. I was just wonder if someone has found an easier entry point to accomplish downloading/skinning at runtime? The fallback would be the Steve texture of course. Thanks, John Quote
prujohn Posted July 2, 2014 Author Posted July 2, 2014 I've made some progress on my own. After I apply a nametag to my NPC entity, I can download a player texture and store it locally. At the moment I'm writing them into a cache directory inside "config/{mymod}/skincache/ What I'm trying to figure out now is where to put these files so that I can address them properly with the "ResourceLocation" object? Once I can point to the file like so: ResourceLocation joy = new ResourceLocation('path/to/downloaded/skin.png'); ...then I should be able to return it here in my render class like so: @Override protected ResourceLocation getEntityTexture(Entity par1Entity){ return ((MyEntity)par1Entity).texture; // assumes I've successfully assigned the new ResourceLocation object to .texture } My problem is that ResourceLocation is (AFAIK) like a virtual directory at runtime, pointing to read-only resource areas? This is where I'm getting lost at the moment. Any guidance appreciated. Thanks! John Quote
delpi Posted July 2, 2014 Posted July 2, 2014 Do you want to download a skin of a player never on your server or one that has been on your server? Anyhow, if you look at how the RenderPlayer deals with the skins this isn't that complicated. The trick is making all players see the same skin. On your entity, you need to pick the name of the 'player' you want it to emulate, set that string as a datawatcher properly so the clients all get it. On the client side, put a custom render for the entity, to utilize code similar to the player against the string you specified and bingo! The one thing I did notice, is there is a small time gap depending on different issues, so make the default skin for the entity Steve or something that you include in your entity texture so it doesn't have to download it. This prevents the ugly white box thing for a the small time lag in certain situations. Quote Long time Bukkit & Forge Programmer Happy to try and help
prujohn Posted July 2, 2014 Author Posted July 2, 2014 My apologies. I should have been more clear about my use case. I'm trying to apply these skins to "dumb" NPC models with limited AI. I basically just want them to walk around while I stream on Twitch (follower perk). I've got all of it done - I can spawn a model with the Steve skin and it wanders around. However I want to be able to switch it's skin to any arbitrary Minecraft IGN when I use a nametag on it. I went down the RenderPlayer path for a while. Unfortunately, it's tightly coupled with the AbstractClientPlayer class, which extends EntityPlayer. I tried using these as base classes for my own entity, but these classes appear to have hooks into the game loop for "player communication" and the constructor also requires a "GameProfile" object. Also minecraft crashes when I try to use them, because it's trying to send messages to the Entity, expecting it to be an actual player (I think). Currently my Entity extends from EntityCreature and my Render class for it extends from RenderLiving. It was pretty trivial for me to apply the Steve skin to the ModelBiped model, so I'm just trying to figure out how to do the same with a downloaded skin at runtime? I can download the skin, but pointing to it with a ResourceLocation object is where I'm currently stuck. Quote
prujohn Posted July 3, 2014 Author Posted July 3, 2014 Solution: I can use the DynamicTexture class and the method .getDynamicTextureLocation() to handle this at runtime (from my RenderLiving class): @Override protected ResourceLocation getEntityTexture(Entity par1Entity){ MyEntity entity= (MyEntity)par1Entity; if (entity.imageTexture != null){ entity.texture = this.renderManager.renderEngine.getDynamicTextureLocation("skin_"+entity.getCustomNameTag(), new DynamicTexture(entity.imageTexture)); entity.imageTexture = null; } return entity.texture; } Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.