Jump to content

Reika

Members
  • Posts

    228
  • Joined

  • Last visited

Everything posted by Reika

  1. This is for the mob harvester. Depending on the enchantments and power supplied, it modifies the drop counts of the mobs it kills. I do that by watching the LivingDropsEvent: @SubscribeEvent public void enforceHarvesterLooting(LivingDropsEvent ev) { if (ev.source instanceof HarvesterDamage) { HarvesterDamage dmg = (HarvesterDamage)ev.source; int looting = dmg.getLootingLevel(); EntityLivingBase e = ev.entityLiving; ArrayList<EntityItem> li = ev.drops; li.clear(); e.captureDrops = true; try { ReikaObfuscationHelper.getMethod("dropFewItems").invoke(e, true, looting); ReikaObfuscationHelper.getMethod("dropEquipment").invoke(e, true, dmg.hasInfinity() ? 100 : looting*4); int rem = RotaryCraft.rand.nextInt(200) - looting*4; if (rem <= 5 || dmg.hasInfinity()) ReikaObfuscationHelper.getMethod("dropRareDrop").invoke(e, 1); } catch (Exception ex) { RotaryCraft.logger.debug("Could not process harvester drops event!"); if (RotaryCraft.logger.shouldDebug()) ex.printStackTrace(); } e.captureDrops = false; } } This is a mob whose type is only known at runtime and will be different for whatever the player decides to kill (including potentially exotic mobs like Withers and Minotaurs).
  2. I have no idea what the "simplimpl" package is, but the Wrapper classes are for the Forge packet system, not vanilla. I take it from that answer that you have no desire whatsoever to use Forge netty support and will only work on a vanilla packet solution. That's cool by me and good luck with it. Not for a vanilla packet subclass, no. It is to me both ugly and probably worse for performance, both in terms of network and CPU load.
  3. I am not trying to do this on custom entity classes. This is for vanilla and other modded mobs, like Creepers, Slime Beetles, and Wisps.
  4. I already do that, but profiling has in the past indicated that method.invoke() and field.get() are still about 5-20x slower than direct access.
  5. I have no idea what the "simplimpl" package is, but the Wrapper classes are for the Forge packet system, not vanilla.
  6. Also, I would go back and put [ code ] tags around that giant block of code or someone more passionate about formatting will probably yell at you.
  7. I have done nothing unusual with these files, and have tried all three of my text editors: Windows Notepad, Notepad++, and EditPad Lite.
  8. I could write a wrapper for the S35 whose read methods are essentially a super() call, but that is a messy solution I would like to avoid. Additionally, it would require some rewrites to my base classes that I would like to avoid if possible.
  9. I have an access transformer in my mod, and it works perfectly in the developer environment. However, it fails to even load in the compiled copy of the game, causing a prompt IllegalAccessError and crash. Having reverse-engineered the access-transformer loading code, I have been left stumped. Here is what I get in my loading logs: And here is the code that loads the Access Transformers (collected from CoreModManager.class, ModAccessTransformer.class, and AccessTransformer.class): private static void discoverCoreMods(File mcDir, LaunchClassLoader classLoader) { FMLRelaunchLog.fine("Discovering coremods"); File coreMods = setupCoreModDir(mcDir); FilenameFilter ff = new FilenameFilter() { @Override public boolean accept(File dir, String name) { return name.endsWith(".jar"); } }; File[] coreModList = coreMods.listFiles(ff); File versionedModDir = new File(coreMods, FMLInjectionData.mccversion); if (versionedModDir.isDirectory()) { File[] versionedCoreMods = versionedModDir.listFiles(ff); coreModList = ObjectArrays.concat(coreModList, versionedCoreMods, File.class); } coreModList = FileListHelper.sortFileList(coreModList); for (File coreMod : coreModList) { FMLRelaunchLog.fine("Examining for coremod candidacy %s", coreMod.getName()); JarFile jar = null; Attributes mfAttributes; try { jar = new JarFile(coreMod); if (jar.getManifest() == null) { // Not a coremod and no access transformer list continue; } ModAccessTransformer.addJar(jar); mfAttributes = jar.getManifest().getMainAttributes(); } catch (IOException ioe) { FMLRelaunchLog.log(Level.ERROR, ioe, "Unable to read the jar file %s - ignoring", coreMod.getName()); continue; } finally { if (jar != null) { try { jar.close(); } catch (IOException e) { // Noise } } } String cascadedTweaker = mfAttributes.getValue("TweakClass"); if (cascadedTweaker != null) { FMLRelaunchLog.info("Loading tweaker %s from %s", cascadedTweaker, coreMod.getName()); Integer sortOrder = Ints.tryParse(Strings.nullToEmpty(mfAttributes.getValue("TweakOrder"))); sortOrder = (sortOrder == null ? Integer.valueOf(0) : sortOrder); handleCascadingTweak(coreMod, jar, cascadedTweaker, classLoader, sortOrder); loadedCoremods.add(coreMod.getName()); continue; } String fmlCorePlugin = mfAttributes.getValue("FMLCorePlugin"); if (fmlCorePlugin == null) { // Not a coremod FMLRelaunchLog.fine("Not found coremod data in %s", coreMod.getName()); continue; } public static void addJar(JarFile jar) throws IOException { AccessTransformer at = new AccessTransformer(jar); if (!at.isEmpty()) { embedded.add(at); } } AccessTransformer(JarFile jar) throws IOException { Manifest manifest = jar.getManifest(); String atList = manifest.getMainAttributes().getValue("FMLAT"); if (atList == null) return; for (String at : atList.split(" ")) { JarEntry jarEntry = jar.getJarEntry("META-INF/"+at); if (jarEntry != null) { processATFile(new JarByteSource(jar,jarEntry).asCharSource(Charsets.UTF_); } } FMLRelaunchLog.fine("Loaded %d rules from AccessTransformer mod jar file %s\n", modifiers.size(), jar.getName()); } As you can see by looking at the code, the fact that I get the first line in my console proves it tries to load my file, and the second line shows that the execution makes it to the line FMLRelaunchLog.fine("Not found coremod data in %s", coreMod.getName()); As you can also see, this line is only reached if jar.getManifest() does not return null. Digging into the instantiation of an AccessTransformer object, it is clear that what is happening is that "atList", the string returned when reading the manifest parameter for "FMLAT", is null, as that is the only thing that would cause the logs to not contain the message "loaded X rules from access transformer...". ----------------------------------------------------------------------------------------------------------------------- So, in short, it is clear that the Manifest file is being found, but the fetch for the FMLAT property returns null. Yet here is my manifest file: Manifest-Version: 1.0 FMLAT: DragonAPI_at.cfg I looked into the java documentation, and I found that it says it requires the manifest file be encoded in UTF-8, rather than ANSI (the windows standard). I tried this, and the game fails to even load my jar, instead printing this: What is going on, and how do I fix it? I have asked multiple people, and so far noone has any idea.
  10. The link works now, but I kind of need to fix my pipe renders. Does anyone else commonly use ISBRHs?
  11. I would expect that there is some way to mark a method to be modified in all subclasses; this system is old enough, and I am surely not the only one to need something like this. I can use reflection, but I am concerned with the performance; this method (used by a mob harvesting machine) is going to be invoked on every mob that passes over it, a number which can be in the hundreds per second.
  12. Why not just have a TileEntity whose TESR is far larger than a block (like my solenoid, generator, and turbines)?
  13. This is true, but I in fact have a special subclass of S35 which only writes the "changed" data, as sending all the data at any rate fast enough to provide acceptable sync is terrible on network load. Because getDescriptionPacket() is what is used to sync data to clients on logging into servers, it must still return a vanilla S35, because a fresh client does need to have all the data synced, whether it just changed serverside or not. Additionally, markBlockForUpdate triggers block and lighting updates, which is very bad for performance.
  14. private void sendPacketToAllAround(S35PacketUpdateTileEntity p, int r) { if (!worldObj.isRemote) { AxisAlignedBB box = ReikaAABBHelper.getBlockAABB(xCoord, yCoord, zCoord).expand(r, r, r); List<EntityPlayerMP> li = worldObj.getEntitiesWithinAABB(EntityPlayerMP.class, box); for (int i = 0; i < li.size(); i++) { EntityPlayerMP entityplayermp = li.get(i); entityplayermp.playerNetServerHandler.sendPacket(p); } } } java.lang.IllegalStateException: Unexpected change in protocol! at net.minecraft.network.NetHandlerPlayServer.onConnectionStateTransition(NetHandlerPlayServer.java:1390) at net.minecraft.network.NetworkManager.processReceivedPackets(NetworkManager.java:236) at net.minecraft.network.NetworkSystem.networkTick(NetworkSystem.java:182) at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:736) at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:624) at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:118) at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:495) at net.minecraft.server.MinecraftServer$2.run(MinecraftServer.java:762)
  15. This crashes with a message "Unexpected Change in protocol!".
  16. Are access transformers really something noone else uses?
  17. Block has a getPickBlock function. Item.getItemForBlock() returns the same thing as you have already been trying.
  18. Ok, but what should I do then? I know it is possible because WAILA shows a good name in its tooltip. WAILA uses the (ItemStack) result of getPickedBlock and gets its name. The enderIO conduit blocks are never normally obtainable, so they do not have proper names for the block instances themselves, only the items you get when crafting or breaking them. The same applies, for example, to RotaryCraft blocks and TE conduits.
  19. OK, an update: I have found a hacky-though-harmless fix for the crash. Simply dump in four "scrap" vertices (I do it at 0,0,0) and then the TesselatorState creation will not crash. It also allowed me to run my normal tessellator reboot code, which allowed me to discover something: When the reboot code is not active, the behavior described in my original post is observed. Turn the reboot code on, and then the flickering is between the correct alpha value and complete transparency. This is a strong indicator of something running twice, or of some alpha threshold application, but I can again confirm that the code and vertices are NOT being called more than once per render cycle. Also, the "flicker" is in fact as follows: While the player is accelerating (velocity is changing in magnitude or direction), the "low alpha" state is rendered. When the player is standing still, or moving at a constant velocity, the "high alpha" state is rendered. What the hell is going on here?
  20. I have the need to send a vanilla-type packet (S35PacketUpdateTileEntity) to clients from the server. Previous to 1.7, the PacketDispatcher was used, but now the new system is only capable of accepting custom packet objects. Short of writing a wrapper for the S35, which I find to be a sloppy solution, how do I send the packet to a given player now? As soon as I know that, functions like sendToAllOnServer and sendToAllAround are easy to replicate.
  21. I actually have a potential though not necessarily recommended solution for you. You can watch the RenderWorldEvent.Post and then use that to draw your block. It is fired after the rest of the renderers run for the pass, and right after the .draw() call is sent to the tessellator, allowing you to change texture bindings and start drawing again. Be warned that you only have access to the render pass, the ChunkCache used in the WorldRenderer and the WorldRenderer itself. What that then means is you can replicate functionality found in WorldRenderer.updateRenderer() (Line 128), but it requires iterating over the chunkcache again to find your blocks, something likely not friendly on performance.
  22. As is stated in the first post, I have already checked for these. Blending is enabled and in default blend (alpha-on-background) mode. Nothing is being rendered twice per call. Positions are unchanged from code which has worked since 1.2.5. Also, your link is broken. EDIT: Oh, this is just perfect. Now I get that TessellatorVertexState crash even when not rebooting the tessellator. No, I have not changed the code since making my first post, and until five minutes ago, it was working, because that pipe block is still in the world and always has been. EDIT 2: It even crashes no matter what, with no code running, as long as renderWorldBlock returns true (which if false prevents any rendering from even being done)!
×
×
  • Create New...

Important Information

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