-
Posts
2638 -
Joined
-
Last visited
-
Days Won
4
Everything posted by Ernio
-
For server to know about key inputs you need to still setup packets. Keyboard is CLIENT side. You will need to implement IExtendedEntityProperties which will hold key-presses per-player as booleans. On client you will need to setup InputEvent.KeyInputEvent which will check for given button and send packet - true when pressed and false when unpressed. Then you can use those boolean server-side to manipulate server-side mouse clicks. Again - mouse clicks (and any other input) is client-sided, you should make all that on CLIENT thread and send to server only info about actual, alredy modified click.
-
Indeed. I belive you/we just discovered glitch in event (or at least unexpected turn). I did some testing, seems like thee crash occurs when game tries to load entity-to-remove from memory (NBT). Explanation: If you would run totally new world - all the new EntityHorse (and others) are constructed and joining world for the first time. That means there is no NBT-loading for them and event will work (test it - it will work on new world). Problem occurs if you would have world in which there was EntityHorse alredy spawned (at least once) and which woud try to actually load its NBT data when joinind the world. In that case game crashes. I'll be damned, but for me it's at least bad, if not horrible. I placed breakpoints and for me it crashed on World.class if (net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.entity.EntityJoinWorldEvent(p_72838_1_, this)) && !flag) return false; this.getChunkFromChunkCoords(i, j).addEntity(p_72838_1_); this.loadedEntityList.add(p_72838_1_); this.onEntityAdded(p_72838_1_); return true; } } public void onEntityAdded(Entity p_72923_1_) { for (int i = 0; i < this.worldAccesses.size(); ++i) { ((IWorldAccess)this.worldAccesses.get(i)).onEntityAdded(p_72923_1_); // crash occured here, on second loop (i = 1), when creeper was added to world, event was canceled and i spawned pig. } } EDIT Some of Forge pros - could you guys look into it? EDIT 2 More directly: Error doesn't occur when creeper is canceled, but when second replacement entity calls "event.world.spawnEntityInWorld(lol);" (using code from prev post). It can obviously be my lack of knowledge about spawning code. How else would you spawn entity replacement if not like I proposed?
-
"limit" is rather something the GPU will decide about. As to your model - consider creating REAL model in Blender and export it to B3D. MUCH less z-fighting in boxes and much more possibilities, also - better looks. No, there is no logical 'limit' to number of boxes, I've personally seen models that I'd consider to be made by madman.
-
So where exactly are you calling "registerPackets()" ? You need to call it in preInit. EDIT More info; This error occurs when there is no packet registered to given packetId - which happens because you forgot to call it (register it).
-
Hmm, welp - this works for me: @SubscribeEvent public void onEntityJoined(EntityJoinWorldEvent event) { if (event.entity instanceof EntityEgg) { event.setCanceled(true); EntityCreeper lol = new EntityCreeper(event.world); lol.setPosition(event.entity.posX, event.entity.posY, event.entity.posZ); event.world.spawnEntityInWorld(lol); } } Try this EXACT code - it has to work. (EDIT: You can also add !world.isRemote - doesn't matter (in this case, it's an example)). What might be wrong: - You are using wrong event bus (should be Forge). - Something's wrong with your constructor - I don't know. - Error is totally elsewhere (weird crash is weird) EDIT
-
[1.8][SOLVED] IInventory internal synchronization - where?
Ernio replied to Ernio's topic in Modder Support
Cut and dried as always. Thanks -
[1.8][SOLVED] IInventory internal synchronization - where?
Ernio replied to Ernio's topic in Modder Support
Just to make sure - if someone is NOT looking at container, the IInventory (in TileEntity) still needs to be synchronized separately? I was interested in code that does that (one I can't find) because I would like to know how vanilla keeps track of changes in IInventory's ItemStacks - is it just scanning all slots every tick for change (like a retarded trol)? -
So I coded something in past and just learned that apparently IInventories are synchornized interanally? Where that happens and who is receiver (players)? (Digging in interfaces is worst kind of searching) EDIT I might be wrong about this, but that would mean that something works while it is not supposed to be working ;_;
-
[1.8] [SOLVED] Waiting for a message to be processed
Ernio replied to SnowyEgret's topic in Modder Support
1. That is simple as hell Check size of changes and if too big - use: CompressedStreamTools.writeCompressed(someNbt, new FileOutputStream(f)); NBTTagCompound nbt = CompressedStreamTools.readCompressed(new FileInputStream(f)); 2. You need to understand the most important fact here: sending 10000 updates of single block is MUCH more of a burden for both sides than sending 1 update with 10000 blocks. Compression is your friend (really good one) - how do you think vanilla sends whole world to clients? You will need to know how block is written to bits and which one (bit) is what. Compressed chunk is almost nothing (a necessity) for minecraft to handle. Alredy noted: lookup vanilla's world sending packets. As to "super-compression" which you tackled at end of post - sending not-full chunk data but only given blocks positions (e.g 500 out of 65536 block). That will be hard and won't change much (again - look at vanilla). To send chunk you need [16][256][16] array of blocks that will with it's size define block pos (e.g [7][78][6]), any attempt at lowering that size will still require you to save the block pos for given pos. Better option: What you can do is to know exacly how much blocks were changed for given chunk. If the number of changes is small you can simply send sinuglar block-change packets (instead of whole chunk). One more thing - Chunk is indeed 16x256x16, but chunk storage is not - it's 16x16x16, which you would know if you looked up code from my previous post. -
HarvestDropsEvent In 1.8 blocks are rendered from .json https://github.com/TheGreyGhost/MinecraftByExample/tree/master/src/main/java/minecraftbyexample/mbe02_block_partial Overall: Blocks aside from their main memory (id) have exact 4 bits to hold additional data (metadata). That allows you to create 16 combinations on one block in given position without using TileEntity. Do you want to split block into 8 (2x2x2) pieces or 512 (8x8x8) pieces? Second case is impossible without placing TileEntity in given position - which will really be quite an overkill for common blocks. In 2x2x2 case you will need to create 8 BLOCKSTATES telling which place to populate with block. Now - the problem is in rotation. 2x2 (2 bits) allows you to have 4 world directions. You need 2x2x2 (3) to have 8 states. So now you have to design system to work nicely. Hint: Look at stairs more (much more). EDIT As to 8x8x8 - statement "impossible" is in regards of using simple Forge+Vanilla coding to do that. It is possible with ASM (obviously) and would require you to rewrite hugeass chunk of game. EDIT 2 Btw. are you sure that is your idea? http://slimevoid.net/littleblocks/
-
[1.8][SOLVED] Can/How to get currently opened container server-side?
Ernio replied to Ernio's topic in Modder Support
That is indeed correct. I wonder why I had that glitch ;o I was printing openContainer and it was always PlayerInv, strange. CLOSED -
[1.8] [SOLVED] Waiting for a message to be processed
Ernio replied to SnowyEgret's topic in Modder Support
As long as block number is not huge-ass, you can set in in "right now" time (meaning current tick), but if that number will get too big (you'll have to test what amount is "too big") then you should split restoration into few ticks. To do that you will need to create restorationQueue system that will be ran from ServerTickEvent (yes, subscribe) and trigerred on player command. I belive you know how to code nice queue - you will be simply getting part of all blocks from restoration and change them per-tick, not all at once, until restoration is done. As mentioned before, to get performance you will need to get into internals: Chunk chunk = world.getChunkFromChunkCoords(chunkX, chunkZ); for (ExtendedBlockStorage storage : chunk.getBlockStorageArray()) This will allow you to edit block-data DIRECTLY. Note that you might need 2 or even 3 phases to make sure that e.g torches are placed after walls around it. Also remember about TileEntity support. What method do I call to update the client? Since you don't really want to sent update per every block: At the end of tick in which you performed mentioned internal restoration process you will need to grab all the chunks that were edited and send them in one terran-loading packet (the one that vanilla sends to clients when they travel across the world). I don't really know exact method (last time I had fun with direct world edits was before 1.5), so I can't help you here. Hint: Just find the vanilla packet and look into callbacks. -
[1.8][SOLVED] Can/How to get currently opened container server-side?
Ernio replied to Ernio's topic in Modder Support
Nope, I alredy checked. That is always PlayerInv. -
[1.8][SOLVED] getGeneralQuads with ISmartItemModel causing massive lag
Ernio replied to coolAlias's topic in Modder Support
Came for solution, stayed for Java debate. I love you guys I feel smarter with every post :* <hugs> Did you just actually read it? -
I wouldn't do that this way, but well. Your choice. Direct answer to your direct question: Entity viewPoint = mc.getRenderViewEntity(); entity.isInRangeToRender3d(viewX, viewY, viewZ) // check render view - your d, d1, d2 entity.isEntityAlive() // check if not dead entity.getDistanceToEntity(viewPoint) // check range entity.canEntityBeSeen(viewPoint) // check obstacles - rayTracing Those will give you working code. Consider not using Frustrum and AABB, no need - you can go with math (rotation) and: for (Object o : mc.theWorld.getLoadedEntityList()) I've always preferred math solutions.
-
Not directly possible. One liquid flow can have many sources. So solution is rather removing all sources. You need to perform block search starting from TileEntity moving recursively in all directions until hitting source block. Keep in mind that water can be falling from very high places so the search in BAD conditions can take quite big chunk of processing power (in comprasion).
-
Explain merging? Model is a ton of coordinates of boxes or different shapes - you can do whatever you want with them, question is - what and why?
-
Create Renderer class with ModelBiped (that you probably know). Most importantly - There is ONE renderer for all entities of given type (NPC). Renderer takes Entity as argument - inside your EntityNPC you will need to store some variable. I suggest it to be some integer "animationPhase". Now - when some action accurs you will need to send packet from server to client that will set this NPC's integer to something. Now in renderer you can make IF that will take that integer from NPC and run animations. Only thing left is to put .png into assets and make static ResourceLocations for them. Simply return different textures for given animationPhase. Example: @SideOnly(Side.CLIENT) public class RenderNPC extends RenderBiped { public RenderNPC(RenderManager rm) { super(rm, new ModelZombie(), 0.5F, 1.0F); } @Override protected ResourceLocation getEntityTexture(Entity entity) { return this.getNPCTexture((EntityNPC)entity); } protected ResourceLocation getNPCTexture(EntityNPC npc) { int animate = npc.getAnimationPhase(); // number of ifs that will get animation phase and return different ResourceLocation. } } Note: DO NOT change value of AnimationPhase inside renderer - rendering runs on rendering loop, not game loop - update that value in update() method of entity (increment /decrement for example - to change phases).
-
[1.8] [SOLVED] Waiting for a message to be processed
Ernio replied to SnowyEgret's topic in Modder Support
I will now have to stop you before you hit a brick wall so hard that you are gonna fell into alcoholism and drugs and look like this: You most certailny don't want to change world per-block. And if you do - you don't want to do that with "send to players" flag. The lag will be so massive you won't be even able to live through it. Few facts: - You don't want to store your "undo" data on client. - You also don't want to store that data on server - more directly - not in RAM, but you CAN. - You too don't want to use setBlockState to replace blocks, and if so - you most certainly don't want to use "update to all players" flag (3 I belive). Now what you want: - Store "undo" selection on server - I'd REALLY consider storing anything beyond some array size to NBT data and save it direcly to disk as schematic. In case player want to load that - indeed, reading from disk will be slower, but I don't imagine you want to store e.g 100MB of map in RAM per-player and per-UndoStorage. -Redesign your "restoration" logic - create ServerTickEvent that will be triggered by player action and which will restore terrain from mentioned server-side storages and/or disk-data (NBT). Now - using TickEvent would allow you to restore LARGE terrains without getting huge-ass lags. (x blocks per tick). - You will VERY soon notice that using "update" flag with a lot of setState methods will cause massive lags, don't do that - change your blocks server-side and send whole chunks to clients - that way you will reduce packets to vanilla-world-loading traffic. - You might also notice that the higher block is (in world) - the more time it will take to set it (in huge numbers) - that is all about light updates - you ca also bypass this by not using update flags per every block, but after whole reload. -
[1.8]Portals that transports both entities AND players?
Ernio replied to NovaViper's topic in Modder Support
Minecarts are the only vanilla entities that can travel through portal. Look them up. -
Do tell - you want to create terrain+entity "map" (like vanilla one) or real full-spectrum rendering?
-
You are never spawning new horse. event.world.spawnEntityInWorld(newHorse); EDIT Oh, that's not all. This way (you are doing), you will be spawning normal horse and advancedHorse, where normal one will simply die in 1 tick time. Proper way of doing this is to cancel EntityJoinWorldEvent and inside it - perform "replacement" spawning. Simple example: @SubscribeEvent public void onAttack(EntityJoinWorldEvent event) { // Checks event.setCanceled(true); // your code }
-
Can I have the Minecraft Forge Adfly links?
Ernio replied to AvantPlays's topic in General Discussion
On http://files.minecraftforge.net/ Go to "Show all downloads" Choose e.g "Installer" for latest version, don't click it, hover mouse over "i" next to it - there is MD5, SHA1 and "Direct Download" link. -
Suggestion for a Forge Hook into changing the player Camera/zoom/viewpoint
Ernio replied to Thornack's topic in Suggestions
Player API / Render Player API This is what you are looking for. I'll just note that what you want to do will still be hard (and I mean it), but using those APIs you can change player's hitbox, camera positions, even attack (eye) boxes ("center of player").