-
Posts
2638 -
Joined
-
Last visited
-
Days Won
4
Everything posted by Ernio
-
[1.7.10] Resizing the players hitbox/collisionbox: How would you do it
Ernio replied to Thornack's topic in Modder Support
I am failing to see how you can possibly find it difficult. Bro, have you ever tried actually looking into vanilla? @SubscribeEvent public void onPlayerTick(TickEvent.PlayerTickEvent event) { event.player.width = 20.0F; event.player.height = 20.0F; event.player.setEntityBoundingBox(new AxisAlignedBB(event.player.getEntityBoundingBox().minX, event.player.getEntityBoundingBox().minY, event.player.getEntityBoundingBox().minZ, event.player.getEntityBoundingBox().minX + 20.0F, event.player.getEntityBoundingBox().minY + 20.0F, event.player.getEntityBoundingBox().minZ + 20.0F)); } BOOM: And YES - my bounding box is right now so big that in picture above I am actually (partially) standing on edge of that grass blocks in front of me. Only thing you have to do is to actually call this shit on both sides. Disclaimer: Do NOT use code I provided. I mean seriously - it was for test (and it's bad). -
@SubscribeEvent public void onPopulateChunk(PopulateChunkEvent.Post event) { Chunk chunk = event.world.getChunkFromChunkCoords(event.chunkX, event.chunkZ); for (ExtendedBlockStorage storage : chunk.getBlockStorageArray()) { if (storage != null) { // iterate through 16x16x16 box arrays which contain blocks. // storage.getBlockByExtId(x, y, z) // storage.set(...) } } }
-
You sure drawing is not called? (print?) The only possibility I see is that you are immidiately closing gui after it's opened. Is there any line in your code that could set screen to null (and you forgot that)?
-
Aside from other problems: 1. Thread safety: http://greyminecraftcoder.blogspot.com.au/2015/01/thread-safety-with-network-messages.html 2. Don't use sendToAll - it sends data to all players, which is no necessary (even bad because clients can't analyse that data anyway, if they don't have player which data should be assigned to). Use combination of PlayerEvent.StartTracking and WorldServer#getEntityTracker() as diesieben suggested.
-
Oh god... I am too damn lazy to explain everything about renderers, so... Catch! /** * @author Ernio */ @SideOnly(Side.CLIENT) public class RenderThrowable extends Render { ResourceLocation rl = new ResourceLocation(ModID + ":" + "textures/something/" + "test" + ".png"); public RenderThrowable(RenderManager rm) { super(rm); } public void doRender(EntityThrowable entity, double x, double y, double z, float f, float partialTicks) { GlStateManager.pushMatrix(); GlStateManager.translate((float) (x), (float) (y), (float) (z)); GlStateManager.enableRescaleNormal(); GlStateManager.rotate(-this.renderManager.playerViewY, 0.0F, 1.0F, 0.0F); GlStateManager.rotate(this.renderManager.playerViewX, 1.0F, 0.0F, 0.0F); GL11.glScalef(entity.getScale(), entity.getScale(), entity.getScale()); this.bindEntityTexture(entity); float fix = 0.00390625F; int xOffset = (entity.getIconIndex() % 16) * 16; int yOffset = (entity.getIconIndex() % 256) * 16; Tessellator tess = Tessellator.getInstance(); WorldRenderer wr = tess.getWorldRenderer(); wr.startDrawingQuads(); wr.setNormal(0.0F, 1.0F, 0.0F); wr.addVertexWithUV((-0.5F), (0.6F), 0.0F, (xOffset + 0) * fix, (yOffset + 16) * fix); wr.addVertexWithUV((0.5F), (0.6F), 0.0F, (xOffset + 16) * fix, (yOffset + 16) * fix); wr.addVertexWithUV((0.5F), (-0.4F), 0.0F, (xOffset + 16) * fix, (yOffset + 0) * fix); wr.addVertexWithUV((-0.5F), (-0.4F), 0.0F, (xOffset + 0) * fix, (yOffset + 0) * fix); tess.draw(); GlStateManager.disableRescaleNormal(); GlStateManager.popMatrix(); super.doRender(entity, x, y, z, f, partialTicks); } protected ResourceLocation getResource(EntityThrowable entity) { return rl; } @Override protected ResourceLocation getEntityTexture(Entity entity) { return this.getResource((EntityThrowable) entity); } @Override public void doRender(Entity entity, double x, double y, double z, float f, float partialTicks) { this.doRender((EntityThrowable) entity, x, y, z, f, partialTicks); } } ClientProxy#init(): RenderingRegistry.registerEntityRenderingHandler(CustomEntityThrowable.class, new RenderThrowable(Minecraft.getMinecraft().getRenderManager())); And btw - this shit right there is badlwy written. I could fix some things, but again - I am lazy. As to what it does - it literally grabs ResourceLocation provided and renders it FLAT (2d) in center of entity facing player. Note that this system is designed to grab 16x16 textures from 256x256 sheet (ResourceLocation) on index based on: int xOffset = (entity.getIconIndex() % 16) * 16; int yOffset = (entity.getIconIndex() % 256) * 16; So go figure To do it for items (grap item texture) look at ItemRenderer classes. Also - for it to work with item (and not pure RL like above), yo uwill need to put texture in texture sheet using TextureStitchEvent (or whatver).
-
[1.7.10] Save NBT data to block when broken and placed
Ernio replied to IvanTune's topic in Modder Support
While logic behind it seems good, you are most certailny making one mistake by using vanilla read/write NBT methods. ((TileEntitySolarPanel)te).writeToNBT(tag); and: te.readFromNBT(stack.getTagCompound()); Will also cause TileEntity placed in new BlockPos set old data from old pos. Meaning: (code from TileEntity.class) public void readFromNBT(NBTTagCompound compound) { this.pos = new BlockPos(compound.getInteger("x"), compound.getInteger("y"), compound.getInteger("z")); if (compound.hasKey("ForgeData")) this.customTileData = compound.getCompoundTag("ForgeData"); } public void writeToNBT(NBTTagCompound compound) { String s = (String)classToNameMap.get(this.getClass()); if (s == null) { throw new RuntimeException(this.getClass() + " is missing a mapping! This is a bug!"); } else { compound.setString("id", s); compound.setInteger("x", this.pos.getX()); compound.setInteger("y", this.pos.getY()); compound.setInteger("z", this.pos.getZ()); if (this.customTileData != null) compound.setTag("ForgeData", this.customTileData); } } All in all causing malfunction. Create your own method that will write/read only data needed. -
1st: I totally forgot you have source in Drops event, sry. 2nd: Your if statement is pretty much it, BUT - #getSourceOfDamage() is direct source. Meaning that for IndirectDamageSource caused by arrow, shoot by player - it will return arrow. #getEntity() will return the shooter. Use 2nd one. 3rd: This is not how you do it. Method should ONLY have Event is its params. Then you pull source from "event.source". 4th: General rule is "do not declare new Random()". World class has its own Random alredy prepared. Hell, even entity itself has one, but protected. Use event.entity.worldObj.rand.
-
If I understand correctly - you want your item to drop only if the mob was killed by player? Totally possible - assign IExtendedEntityProperties to every living entity, store boolean defaulted to false. Change boolean to true using LivingDeathEvent if event.source.getEntity() instanceof EntityPlayer. Use IEEP's boolean in LivingDropsEvent to decide if mob was killed by player. Other option would be without IEEP. Simply spawn EntityItem in world using LivingDeathEvent. But that way it goes beyond vanilla drops system.
-
TBH - there is none - from code side.
-
IItemRenderer is deprecated as of 1.8. In 1.8 everything has been replaced by pregenerated models or combination of them which can also be easily rotated/moved around. Goal is use cached models instead of rendering everything "on run" with GL. Now - if you need custom rendering you will need ISmartItemModel which has tutorial here: https://github.com/TheGreyGhost/MinecraftByExample/tree/master/src/main/java/minecraftbyexample/mbe15_item_smartitemmodel (assets included in their directory). Note that there are a lot more model interfaces that can be used to archieve probably anything you want. Only way to learn true power of 1.8 rendering is to sit, analyse and code for hours.
-
[SOLVED] [1.8] Crashes with Certain Methods in Custom Particle Class
Ernio replied to Furgl's topic in Modder Support
That is totally possible, but don't even think about doing that. Easy way would be to indeed - just spawn particle and make particle send packet to server telling that it hit something (you would probably use entity.entityId in this case). BUT: Easy != Good. Giving clients power to dictate what server should do not only opens ways to do bad stuff to server (remember - server doesn't know about particles, if someone would want he could spawn client-particle everywhere around him and tell server to kill everything around), but also makes MP few times worse. Different client have different particles, each client can have latency/lag, small things will cause massive calculation errors. Proper way of doing what you want is what I alredy told you. (server=side entity). There is however mid-solution. You can actually do everything on client and then just send packet to server, but whenever server receives packet you would need to make calculations that would define if action was legal (e.g enemy hit is in range and is in proper angle (not behind your back). This is STILL BAD solution, but better than just saying "attack that guy, because I (client) tell you". Cheers! -
[SOLVED] [1.8] Crashes with Certain Methods in Custom Particle Class
Ernio replied to Furgl's topic in Modder Support
I see what you are attempting to do - Fire-breathing. As mentioned - particles are client-side beings. They don't even exist on server. Imagine if server would have 100 players that all spawn hundreds of particles and server has to move tham around and send position updates about them to all players around - that would kill performance. I actually have a spell that does mentioned "Fire-breathing". You will need to extend EntityThrowable or Entity (depends on logic). When starting using your "flames" you would constantly spawn your FlameEntity on server (spawning entities happens only on server, particles on client) - you would need only one per few ticks, about 5-10 would be fine. Server would only have that FlameEntity that would actually be one which ignites stuff from server side and client would just add its own particles (Display-only for cool effect). -
What is the best way to track a seemingly untrackable crash
Ernio replied to The_Fireplace's topic in Modder Support
Well, you could work with breakpoints and see after what operation it crashes, thet would narrow down possibilities and tell where to look. More important questions would be - when did this started happning? Do you have versioning (working backups)? If you can't think of ANY place this can be coming from I suggest commenting out parts of your mod and test if it works without it. (start with tick events, entities, tile entities (onUpdate() method mostly). -
Not to sound rude (seriously) but there is nothing that's gonna explain (this particular) method better than reading it and its callbacks. You'd be better off just analysing it. My guess is that anyone who'd attempt to "explain" it, when diesieben alredy gave you self-explainatory code would end up with something like this (which won't really help): /** Moves Element e to Collection C. */ public void moveElementToCollection(Element e, Collection C) { ... } Unless you are asking about Containers, Inventories and Slots themselves, then that would be a totally different answer or should I say - essay (there is a lot to talk about). But, since it's support, where lies the problem?
-
Just wanted to let you know that hiding vanilla inv behind yours on client side, it not equal to replacing it. You can still open vanilla's one. To not be able to do that you would need Gui/Container events (which are available).
-
[SOLVED] [1.8] Crashes with Certain Methods in Custom Particle Class
Ernio replied to Furgl's topic in Modder Support
ConcurrentModificationException happens when you are accessing not synchronized collection (here: HashMap) from wrong thread. To make it clearer: * Particles are client-side ONLY. You are not allowed to spawn them from server thread. You should always inform (e.g by packet) client that "hey, you should spawn particle now" and client should do that. * Since Particles are client-sided, they DO NOT have access to any of server logic. They can only relay on client's data - server doesn't even know if they exist. * You cannot use !world.isRemote (server) whenever you are dealing with particles. So yeah - since each client spawns its own particles and has a little different info (e.g on two different clients a Zombie can stand a little bit furteher than on the other). You cannot expect two clients to act same. We need code, if above won't lead to solution. Also - ever tried running your mod on dedicated + client? I think you might see more problems. -
[1.7.10] [SOLVED] Entity.SetSize cannot be called outside constructor?
Ernio replied to Frag's topic in Modder Support
My guess is that it works perfectly fine. Problem is most likely in sychronization. Each - Server and Client Thread, has its own entity. How +/- looks: 1. Whenever you make "new Entity(...)" you (should) do this on server (!world.isRemote). 2. Then, if you World#spawnEntityInWorld(...) (still on server), the server will send spawning packet to client thread that contains all data needed to spawn given entity. 3. That packet will contain "vanilla" data (id, position, etc), but can also contain IEntityAdditionalSpawnData (implementing this interface allows to send special data, ONCE when entity is spawned). 4. Client receives packet and recreates entity from providded data, it also binds entity with temporary (per-world-join) entityId, that links server entity with client entity. Now, somewhere in this logic you need to notify both sides that you want to change entity's size. To do that you need to perform Entity#setSize(...) on BOTH threads. And to do that you need to send packet! (or use IEntityAdditionalSpawnData, but that is ONLY once, on spawn). Packets tutorial: http://www.minecraftforum.net/forums/mapping-and-modding/mapping-and-modding-tutorials/2137055-1-7-2-customizing-packet-handling-with Short: http://www.minecraftforge.net/forum/index.php/topic,20135.0.html Thread safety: Only for 1.8 http://greyminecraftcoder.blogspot.com.au/2015/01/thread-safety-with-network-messages.html EDIT: Your packet: After learning (tutorial above) about packets, you will need to send: int entityId; // get: "entity.entityId;" // from world: world.getEntityById(entityId); float width; float height; -
Not to be rude, but: From what I see now I can tell you - you are not new to modding, not even Java, but programming itself. How do you expect that to work? Calling method wont render it constantly, even if - it would still be wrong Only way to tell how it should be done (besides "go look at vanilla") is by writing WHOLE tutorial, and there are alredy plenty of those alredy. You either want to render a model or you want to make entity/block with some model and let MC handle it for you. For entities with models - lookup any entity tutorial there is. You will need Entity, Renderer, Model and: RenderingRegistry.registerEntityRenderingHandler For non-entity rendering: It really depend on what you need. In any case - you NEED to learn how to work with forge events (again - any tutorial on google). Then get to know client events. They are located in net.minecraftforge.client.event.
-
MinecraftForge.EVENT_BUS.register(new ForgeEvents()); This event belongs to Forge events. To know that look at package. There are 2 main buses - FML and Forge, and few side ones - for world-gens mainly.
-
[1.8] Need clarification on the seperation of client and server
Ernio replied to a topic in Modder Support
Basically - what client sees, client has. Note that some of TileEntities are not always synchronized to client (their data). Some other stuff too. http://www.minecraftforge.net/forum/index.php/topic,33918.msg178740.html#msg178740 -
Well, player requires his fields, BUT you could extend EntityPlayer and make his methods NOT use fields from constructor and leave them null. net.minecraftforge.common.util.FakePlayer for example gives you dummy, but still requires running server. If you remove all MincraftServer references (by overriding methods) you could thoretically leave those null and use CustomEntityPlayer in rendering method (one from gui). Just a thought. As to non-tricky ways - simply make living entity that uses similar-to-player rendering code and make it use your (player's?) texture.
-
While world timestamps are cool for most stuff and using them is often advertised on this forum with great praise, I must say that I am quite amazed how many people miss the fact or forget to mention that there can be more worlds than just one. "If something can fail, it will." - Me. - And above (world timestamps) is among those things. Solution is quite obvious (ServerTickEvent and global timestamp).
-
This should be in modder support. Did you register your event class? Are other events also not called?
-
Doesn't matter what is in that Superhuman Project - if you want any entity (inthis case - player) to hold additional data: * IExtendedEntityProperties http://www.minecraftforum.net/forums/mapping-and-modding/mapping-and-modding-tutorials/1571567-forge-1-6-4-1-8-eventhandler-and * Packets http://www.minecraftforum.net/forums/mapping-and-modding/mapping-and-modding-tutorials/2137055-1-7-x-1-8-customizing-packet-handling-with http://www.minecraftforge.net/forum/index.php/topic,20135.0.html * For rendering: - RenderGameOverlayEvent Overally - might take some time if you are not fluent with Java, otherwise - easy.
-
Currently there is no such hook (note that I might have missed something). Only idea that come to my mind (and would work) is to make your own CustomEntityMinecart (with all sub-classes) and use EntityJoinWorld event to replace vanilla ones. Sadly this way is not very good. Make PR or use ASM.