Jump to content

ellipsis

Members
  • Posts

    4
  • Joined

  • Last visited

Everything posted by ellipsis

  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)
×
×
  • Create New...

Important Information

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