Jump to content
View in the app

A better way to browse. Learn more.

Forge Forums

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

ellipsis

Members
  • Joined

  • Last visited

  1. I have some code using ASM that can replace methods in classes that aren't statically initialized, but I'm having trouble replacing Block methods, since it's statically initialized. Can I either reload all classes by recreating the Forge RelaunchClassLoader or plug my custom IClassTransformer into the RelaunchClassLoader before the vanilla classes are loaded? EDIT: I fixed the problem by making a core mod to handle hooking and then injecting proxy calls to the needed methods.
  2. What should I implement instead of IInventory?
  3. I'm using the latest version of Forge and I get a crash when I try to run my mod outside of MCP. Here's the crash log: ---- Minecraft Crash Report ---- // I let you down. Sorry Time: 9/9/12 4:06 PM Description: Failed to start game cpw.mods.fml.common.LoaderException: java.lang.reflect.InvocationTargetException at cpw.mods.fml.common.LoadController.transition(LoadController.java:102) at cpw.mods.fml.common.Loader.initializeMods(Loader.java:625) at cpw.mods.fml.client.FMLClientHandler.finishMinecraftLoading(FMLClientHandler.java:174) at net.minecraft.client.Minecraft.a(Minecraft.java:450) at net.minecraft.client.Minecraft.run(Minecraft.java:737) at java.lang.Thread.run(Thread.java:680) Caused by: java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at cpw.mods.fml.common.FMLModContainer.handleModStateEvent(FMLModContainer.java:371) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at com.google.common.eventbus.EventHandler.handleEvent(EventHandler.java:69) at com.google.common.eventbus.SynchronizedEventHandler.handleEvent(SynchronizedEventHandler.java:45) at com.google.common.eventbus.EventBus.dispatch(EventBus.java:317) at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:300) at com.google.common.eventbus.EventBus.post(EventBus.java:268) at cpw.mods.fml.common.LoadController.propogateStateMessage(LoadController.java:124) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at com.google.common.eventbus.EventHandler.handleEvent(EventHandler.java:69) at com.google.common.eventbus.SynchronizedEventHandler.handleEvent(SynchronizedEventHandler.java:45) at com.google.common.eventbus.EventBus.dispatch(EventBus.java:317) at com.google.common.eventbus.EventBus.dispatchQueuedEvents(EventBus.java:300) at com.google.common.eventbus.EventBus.post(EventBus.java:268) at cpw.mods.fml.common.LoadController.distributeStateMessage(LoadController.java:81) at cpw.mods.fml.common.Loader.initializeMods(Loader.java:624) ... 4 more Caused by: java.lang.NoClassDefFoundError: robocraft/common/robots/android/EntityAndroidRobot at robocraft.common.RoboCraft.load(RoboCraft.java:86) ... 30 more Caused by: java.lang.ClassNotFoundException: robocraft.common.robots.android.EntityAndroidRobot at cpw.mods.fml.relauncher.RelaunchClassLoader.findClass(RelaunchClassLoader.java:100) at java.lang.ClassLoader.loadClass(ClassLoader.java:307) at java.lang.ClassLoader.loadClass(ClassLoader.java:248) ... 31 more Caused by: java.lang.ClassFormatError: Duplicate method name&signature in class file robocraft/common/robots/android/EntityAndroidRobot at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632) at java.lang.ClassLoader.defineClass(ClassLoader.java:616) at java.lang.ClassLoader.defineClass(ClassLoader.java:466) at cpw.mods.fml.relauncher.RelaunchClassLoader.findClass(RelaunchClassLoader.java:94) ... 33 more Relevant Details: - Minecraft Version: 1.3.2 - Operating System: Mac OS X (i386) version 10.6.8 - Java Version: 1.6.0_22, Apple Inc. - Java VM Version: Java HotSpot(TM) Client VM (mixed mode), Apple Inc. - Memory: 510316592 bytes (486 MB) / 550305792 bytes (524 MB) up to 1070399488 bytes (1020 MB) - JVM Flags: 3 total; -Xbootclasspath/a:/System/Library/PrivateFrameworks/JavaApplicationLauncher.framework/Resources/LauncherSupport.jar -Xms512M -Xmx1024M - FML: FML v3.0.165.344 Minecraft Forge 4.0.0.241 3 mods loaded, 3 mods active FML [Forge Mod Loader] (coremods) Unloaded->Constructed->Pre-initialized->Initialized Forge [Minecraft Forge] (coremods) Unloaded->Constructed->Pre-initialized->Initialized ellipsis_RoboCraft [RoboCraft] (robocraft.zip) Unloaded->Constructed->Pre-initialized->Errored - LWJGL: 2.4.2 - OpenGL: ATI Radeon HD 2400 XT OpenGL Engine GL version 2.1 ATI-1.6.36, ATI Technologies Inc. - Is Modded: Definitely; 'forge,fml' - Type: Client - Texture Pack: Default - Profiler Position: N/A (disabled) and here's the EntityAndroidRobot class: package robocraft.common.robots.android; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.Iterator; import java.util.List; import net.minecraft.src.DamageSource; import net.minecraft.src.Entity; import net.minecraft.src.EntityItem; import net.minecraft.src.EntityLightningBolt; import net.minecraft.src.EntityLiving; import net.minecraft.src.EntityPlayer; import net.minecraft.src.IInventory; import net.minecraft.src.ItemStack; import net.minecraft.src.NBTTagCompound; import net.minecraft.src.NBTTagList; import net.minecraft.src.PotionEffect; import net.minecraft.src.Vec3; import net.minecraft.src.World; import robocraft.common.InventoryRobot; import robocraft.common.RoboCraft; import robocraft.common.ai.IRobotController; import robocraft.common.ai.IRobotControllerItem; import robocraft.common.ai.pathing.DynamicPathFinder; import robocraft.common.motion.IMotionModule; import robocraft.common.motion.IMotionModuleItem; import robocraft.common.power.IPowerCellItem; import robocraft.common.power.IPowerSupplier; import robocraft.common.power.IPowerTransfer; import robocraft.common.power.IPowerTransferItem; import robocraft.common.sensors.IRobotSensor; import robocraft.common.sensors.IRobotSensorItem; import robocraft.common.tools.IRobotManipulator; import robocraft.common.tools.IRobotManipulatorItem; import robocraft.common.upgrades.IRobotUpgrade; import robocraft.common.upgrades.IRobotUpgradeItem; import robocraft.util.NBTUtilities; import cpw.mods.fml.common.Side; import cpw.mods.fml.common.asm.SideOnly; public class EntityAndroidRobot extends EntityRobot implements IInventory { // Item interfaces private IRobotController controller; private IRobotSensor sensor; private IPowerTransfer transfer; private IMotionModule motion; private IPowerSupplier battery; private InventoryRobot inventory; private IRobotManipulator leftManip, rightManip; private IRobotUpgrade modules[] = new IRobotUpgrade[6]; // Stacks for the items private ItemStack controllerStack, sensorStack, manipLeft, manipRight; // Slots // 0-3 private ItemStack powerStack, motionStack, transferStack; // Slots 4-6 private ItemStack upgrades[] = new ItemStack[6]; // Persistant state // State private boolean suspended; private int ticksSinceSync; private DynamicPathFinder dynPather; public EntityAndroidRobot(World w) { super(w); texture = "/robocraft/mob/AndroidRobot.png"; controller = null; sensor = null; transfer = null; motion = null; battery = null; leftManip = rightManip = null; inventory = new InventoryRobot(this); // The size of a large chest controllerStack = sensorStack = manipLeft = manipRight = powerStack = null; motionStack = transferStack = null; upgrades[0] = upgrades[1] = upgrades[2] = upgrades[3] = upgrades[4] = upgrades[5] = null; suspended = false; ticksSinceSync = 0; this.height = 2.0f; this.entityType = "humanoid"; dynPather = new DynamicPathFinder(worldObj, this, false, false); getNavigator().setAvoidSun(false); getNavigator().setAvoidsWater(false); getNavigator().setBreakDoors(false); getNavigator().setCanSwim(true); getNavigator().setSpeed(20.0f); getNavigator().setEnterDoors(true); } @Override protected void entityInit() { super.entityInit(); dataWatcher.addObject(16, Byte.valueOf((byte) 0)); dataWatcher.addObject(17, ""); } private boolean consumeEnergy(float e) { if (battery == null) return false; return (battery.removeEnergy(e) == e); } @Override public void onEntityUpdate() { super.onEntityUpdate(); // Update energy transfer system if (transfer != null && battery != null) transfer.updateEnergyTransfer(battery, this); // Don't run any motion or AI if we're suspended or our battery is dead if (battery == null || battery.getEnergy() == 0.0f || (dataWatcher.getWatchableObjectByte(16) == 1)) { if (battery != null) { battery.tick(); battery.removeEnergy(0.01f); } stopMoving(); this.isJumping = false; return; } battery.tick(); battery.removeEnergy(0.5f); // Update AI module if (controller != null) { controller.update(this); battery.removeEnergy(controller.energyUsageThisTick()); } // Iterate through upgrades for (int i = 0; i < 6; i++) if (modules[i] != null) { modules[i].update(this); } } @Override public void onLivingUpdate() { super.onLivingUpdate(); if(isDead) return; // Update the important AI stuff this.worldObj.theProfiler.startSection("navigation"); dynPather.update(); this.worldObj.theProfiler.endSection(); this.worldObj.theProfiler.startSection("controls"); this.worldObj.theProfiler.startSection("move"); getMoveHelper().onUpdateMoveHelper(); this.worldObj.theProfiler.endStartSection("look"); getLookHelper().onUpdateLook(); this.worldObj.theProfiler.endStartSection("jump"); getJumpHelper().doJump(); this.worldObj.theProfiler.endSection(); this.worldObj.theProfiler.endSection(); // Check collision with items List var3 = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.expand(1.0D, 0.0D, 1.0D)); if (var3 != null) { Iterator var4 = var3.iterator(); while (var4.hasNext()) { Entity var5 = (Entity) var4.next(); if (!var5.isDead && (var5 instanceof EntityItem)) { // Pickup the item EntityItem i = (EntityItem) var5; if (this.inventory.addItemStackToInventory(i.item)) { this.worldObj .playSoundAtEntity( this, "random.pop", 0.2F, ((this.rand.nextFloat() - this.rand .nextFloat()) * 0.7F + 1.0F) * 2.0F); if (i.item.stackSize <= 0) i.setDead(); } } } } } @Override public void updateEntityActionState() { // We override this so the robot doesn't turn towards players } @Override public boolean interact(EntityPlayer par1EntityPlayer) { if (par1EntityPlayer == null || worldObj == null) return false; String owner = getOwner(); if (owner != "" && par1EntityPlayer.username != owner && !RoboCraft.debugging) return false; par1EntityPlayer.openGui(RoboCraft.instance, 40, worldObj, entityId, 0, 0); return true; } @Override public void onStruckByLightning(EntityLightningBolt par1EntityLightningBolt) { if (battery != null) { float r = battery.addEnergy(1000); if (r > 0) this.worldObj.createExplosion(this, this.posX, this.posY, this.posZ, r / 100); } } @Override public void readEntityFromNBT(NBTTagCompound var1) { super.readEntityFromNBT(var1); // Load inventory info NBTUtilities.loadInventory(var1.getTagList("Items"), this); inventory.readFromNBT(var1.getTagList("ChestItems")); // Construct modules from our inventory if (controllerStack != null && (controllerStack.getItem() instanceof IRobotControllerItem)) { controller = ((IRobotControllerItem) (controllerStack.getItem())) .getControllerInstance(controllerStack); controller.initController(); } if (sensorStack != null && (sensorStack.getItem() instanceof IRobotSensorItem)) sensor = ((IRobotSensorItem) (sensorStack.getItem())) .getSensorInstance(sensorStack); if (transferStack != null && (transferStack.getItem() instanceof IPowerTransferItem)) transfer = ((IPowerTransferItem) (transferStack.getItem())) .getTransferInstance(transferStack); if (motionStack != null && (motionStack.getItem() instanceof IMotionModuleItem)) motion = ((IMotionModuleItem) (motionStack.getItem())) .getModuleInstance(motionStack); if (powerStack != null && (powerStack.getItem() instanceof IPowerCellItem)) battery = ((IPowerCellItem) (powerStack.getItem())) .getPowerSupplierInstance(powerStack); if (manipLeft != null && (manipLeft.getItem() instanceof IRobotManipulatorItem)) leftManip = ((IRobotManipulatorItem) (manipLeft.getItem())) .getManipulatorInstance(manipLeft); if (manipRight != null && (manipRight.getItem() instanceof IRobotManipulatorItem)) rightManip = ((IRobotManipulatorItem) (manipRight.getItem())) .getManipulatorInstance(manipRight); for (int i = 0; i < 6; i++) if (upgrades[i] != null && (upgrades[i].getItem() instanceof IRobotUpgradeItem)) modules[i] = ((IRobotUpgradeItem) (upgrades[i].getItem())) .getUpgradeInstance(upgrades[i]); // Load the owner setOwner(var1.getString("Owner")); } @Override public void writeEntityToNBT(NBTTagCompound var1) { super.writeEntityToNBT(var1); // Make sure all our modules save their states if (controller != null) controller.forceSave(); if (sensor != null) sensor.forceSave(); if (transfer != null) transfer.forceSave(); if (motion != null) motion.forceSave(); if (battery != null) battery.forceSave(); if (leftManip != null) leftManip.forceSave(); if (rightManip != null) rightManip.forceSave(); for (int i = 0; i < 6; i++) if (modules[i] != null) modules[i].forceSave(); var1.setTag("Items", NBTUtilities.saveInventory(this)); var1.setTag("ChestItems", inventory.writeToNBT(new NBTTagList())); var1.setString("Owner", getOwner()); } @Override public int getMaxHealth() { return 1; } @Override public boolean attackEntityFrom(DamageSource par1DamageSource, int par2) { if (!this.worldObj.isRemote) { if (par1DamageSource == DamageSource.inWall) return false; if (par1DamageSource == DamageSource.starve) return false; return super.attackEntityFrom(par1DamageSource, par2); } return false; } @Override protected int applyArmorCalculations(DamageSource par1DamageSource, int par2) { return super.applyArmorCalculations(par1DamageSource, par2); } @Override public void onDeath(DamageSource par1DamageSource) { System.out.println("On Death on " + ((worldObj.isRemote) ? "Remote" : "Local")); // Drop upgrades if (controllerStack != null) { controller.deinitController(); this.entityDropItem(controllerStack, 0.2f); } if (sensorStack != null) { this.entityDropItem(sensorStack, 0.2f); } if (manipLeft != null) { this.entityDropItem(manipLeft, 0.2f); } if (manipRight != null) { this.entityDropItem(manipRight, 0.2f); } if (powerStack != null && !battery.getItem().isVolatile()) { this.entityDropItem(powerStack, 0.2f); } if (motionStack != null) { this.entityDropItem(motionStack, 0.2f); } if (transferStack != null) { this.entityDropItem(transferStack, 0.2f); } for (int i = 0; i < 6; i++) if (upgrades[i] != null) this.entityDropItem(upgrades[i], 0.2f); // Drop items from inventory inventory.dropAllItems(); if (battery != null) { if (battery.getItem().isVolatile()) this.worldObj.createExplosion(this, this.posX, this.posY, this.posZ, battery.getEnergy() / 10000); } } @Override public boolean canBreatheUnderwater() { return true; } @Override protected boolean canDespawn() { return false; } @Override @SideOnly(Side.CLIENT) public ItemStack getHeldItem() { return super.getHeldItem(); } @Override public boolean isPotionApplicable(PotionEffect par1PotionEffect) { return false; } @Override public int getSizeInventory() { return 13; } @Override public ItemStack getStackInSlot(int var1) { if (var1 <= 6) { switch (var1) { case 0: return controllerStack; case 1: return sensorStack; case 2: return manipLeft; case 3: return manipRight; case 4: return powerStack; case 5: return motionStack; case 6: return transferStack; } } else { return upgrades[var1 - 7]; } return null; } @Override public ItemStack decrStackSize(int var1, int var2) { System.out.println("decrStackSize on " + ((worldObj.isRemote) ? "Remote" : "Local")); if (getStackInSlot(var1) != null) { if (var1 <= 6) { // We had a module removed } else { if (modules[var1 - 7] != null) { modules[var1 - 7].deinitModule(this); modules[var1 - 7] = null; } } if (getStackInSlot(var1).stackSize <= var2) { ItemStack s = getStackInSlot(var1); setInventorySlotContents(var1, null); onInventoryChanged(); return s; } ItemStack s1 = getStackInSlot(var1).splitStack(var2); if (getStackInSlot(var1).stackSize == 0) setInventorySlotContents(var1, null); onInventoryChanged(); return s1; } else { return null; } } @Override public ItemStack getStackInSlotOnClosing(int var1) { return getStackInSlot(var1); } @Override public void setInventorySlotContents(int var1, ItemStack var2) { if (var1 <= 6) { switch (var1) { case 0: controllerStack = var2; if (var2 != null) { controller = ((IRobotControllerItem) var2.getItem()) .getControllerInstance(var2); controller.initController(); } else if(controller != null) { controller.deinitController(); controller = null; } break; case 1: sensorStack = var2; if (var2 != null) sensor = ((IRobotSensorItem) var2.getItem()) .getSensorInstance(var2); else sensor = null; break; case 2: manipLeft = var2; if (var2 != null) leftManip = ((IRobotManipulatorItem) var2.getItem()) .getManipulatorInstance(var2); else leftManip = null; break; case 3: manipRight = var2; if (var2 != null) rightManip = ((IRobotManipulatorItem) var2.getItem()) .getManipulatorInstance(var2); else rightManip = null; break; case 4: powerStack = var2; if (var2 != null) battery = ((IPowerCellItem) var2.getItem()) .getPowerSupplierInstance(var2); else battery = null; break; case 5: motionStack = var2; if (var2 != null) motion = ((IMotionModuleItem) var2.getItem()) .getModuleInstance(var2); else motion = null; break; case 6: transferStack = var2; if (var2 != null) transfer = ((IPowerTransferItem) var2.getItem()) .getTransferInstance(var2); else transfer = null; break; } } else { upgrades[var1 - 7] = var2; if (var2 != null) { modules[var1 - 7] = ((IRobotUpgradeItem) (var2.getItem())) .getUpgradeInstance(var2); modules[var1 - 7].initModule(this); } else if(modules[var1 - 7] != null){ modules[var1-7].deinitModule(this); modules[var1-7] = null; } } if (var2 != null && var2.stackSize > getInventoryStackLimit()) { var2.stackSize = getInventoryStackLimit(); } onInventoryChanged(); } @Override public String getInvName() { return "Android"; } @Override public int getInventoryStackLimit() { return 1; } @Override public void onInventoryChanged() { } @Override public boolean isUseableByPlayer(EntityPlayer var1) { if (worldObj == null) return true; return var1.getDistanceSq((double) posX + 0.5d, (double) posY + 0.5d, (double) posZ + 0.5d) <= 64d; } @Override public void openChest() { if (worldObj == null) return; if(!worldObj.isRemote) dataWatcher.updateObject(16, Byte.valueOf((byte) 1)); } @Override public void closeChest() { suspended = false; if(!worldObj.isRemote) dataWatcher.updateObject(16, Byte.valueOf((byte) 0)); } @Override public void lookAt(int x, int y, int z) { // Last two are the pitch and yaw velocity getLookHelper().setLookPosition(x, y, z, 5, 5); } @Override public void moveTo(int x, int y, int z) { // Last one is speed dynPather.setTarget(x, y, z); } @Override public boolean isMoving() { return dynPather.isMoving(); } @Override public void stopMoving() { Vec3 lv = getLookVec(); getLookHelper().setLookPosition(lv.xCoord, lv.yCoord, lv.zCoord, 0, 0); getMoveHelper().setMoveTo(this.posX, this.posY, this.posZ, 0); dynPather.abort(); } @Override public void doJump() { getJumpHelper().setJumping(); } @Override public void writeRobotState(DataOutputStream s) throws IOException { } @Override public void readRobotState(DataInputStream s) throws IOException { } @Override public int getEntityID() { return entityId; } @Override public EntityLiving getEntity() { return this; } public String getOwner() { return dataWatcher.getWatchableObjectString(17); } public void setOwner(String s) { if(!worldObj.isRemote) dataWatcher.updateObject(17, s); } @Override public IRobotController getController() { return controller; } @Override public IInventory getInventory() { return inventory; } @Override public IRobotSensor getSensor() { return sensor; } @Override public void transmitAIState(DataOutputStream s) { // TODO Auto-generated method stub } @Override public void decodeAIState(DataInputStream s) { // TODO Auto-generated method stub } public DynamicPathFinder getPathFinder() { return dynPather; } } I really can't seem to figure this out. Does anyone have any ideas?
  4. I'm making a mod that includes chemistry (among other things), and I have a test tube item. I'm using addInformation to add the amount and some other info, but Minecraft's built in font renderer doesn't support subscripts, which I want to use to draw the chemical formula. I don't want to modify GuiContainer, so a hook for item tooltip rendering would be really useful. This could be implemented by adding an interface "IItemTooltipRenderer", then doing a check in GuiContainer.drawScreen to see if the item is an instance of IItemTooltipRenderer and calling the item's rendering logic instead of the standard logic. EDIT: Apparently Unicode subscript characters work, but this would still be useful to render icons representing element properties (radiation, acid, flammable, etc)

Important Information

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

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.