Jump to content

ellipsis

Members
  • Posts

    4
  • Joined

  • Last visited

Posts 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. 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?

  3. 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.