package mods.ocminecart.common.minecart; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.Loader; import cpw.mods.fml.common.Optional; import mods.ocminecart.Settings; import mods.ocminecart.common.util.BitUtil; import mods.railcraft.api.carts.IEnergyTransfer; import mods.railcraft.api.electricity.IElectricMinecart; import mods.railcraft.client.emblems.EmblemToolsClient; import mods.railcraft.common.emblems.EmblemToolsServer; import net.minecraft.block.Block; import net.minecraft.block.BlockRailBase; import net.minecraft.entity.item.EntityMinecart; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.DamageSource; import net.minecraft.util.MathHelper; import net.minecraft.util.ResourceLocation; import net.minecraft.world.World; //Is the Base for a solid, self powered cart with a brake. //Later I will add the Railcraft integration here @Optional.InterfaceList({ @Optional.Interface(iface = "mods.railcraft.api.carts.IEnergyTransfer", modid = "Railcraft") , @Optional.Interface(iface = "mods.railcraft.api.electricity.IElectricMinecart", modid = "Railcraft") }) public abstract class AdvCart extends EntityMinecart implements IEnergyTransfer, IElectricMinecart { private ChargeHandler charge; public AdvCart(World p_i1713_1_, double p_i1713_2_, double p_i1713_4_, double p_i1713_6_) { super(p_i1713_1_, p_i1713_2_, p_i1713_4_, p_i1713_6_); this.setDisplayTileData(0); } public AdvCart(World p_i1713_1) { super(p_i1713_1); this.setDisplayTileData(0); } protected void entityInit() { super.entityInit(); if(Loader.isModLoaded("Railcraft") && FMLCommonHandler.instance().getEffectiveSide().isServer()) charge = new ChargeHandler(this, ChargeHandler.Type.USER, Settings.ComputerCartETrackBuf, Settings.ComputerCartETrackLoss); this.dataWatcher.addObject(3, (byte)0); // Booleans (is Locked, Brake enabled) this.dataWatcher.addObject(4, 0.0F); //Engine speed this.dataWatcher.addObject(5, ""); //Emblem id [Railcraft] // Free DataWatcher 6-16, 23-32 } protected final void setBrake(boolean b){ this.dataWatcher.updateObject(3, BitUtil.setBit(b, this.dataWatcher.getWatchableObjectByte(3), 0)); } protected final boolean getBrake(){ return BitUtil.getBit(this.dataWatcher.getWatchableObjectByte(3), 0); } protected final void setEngine(double d){ this.dataWatcher.updateObject(4, (float)d); } protected final double getEngine(){ return this.dataWatcher.getWatchableObjectFloat(4); } public final boolean isLocked(){ return BitUtil.getBit(this.dataWatcher.getWatchableObjectByte(3), 1); } public final boolean isEngineActive(){ return this.getEngine()!=0 && !this.isLocked() && !this.getBrake() && this.onRail(); } public void writeEntityToNBT(NBTTagCompound nbt){ super.writeEntityToNBT(nbt); NBTTagCompound tag = new NBTTagCompound(); tag.setDouble("enginespeed", this.dataWatcher.getWatchableObjectFloat(4)); tag.setBoolean("brake", BitUtil.getBit(this.dataWatcher.getWatchableObjectByte(3), 0)); if(Loader.isModLoaded("Railcraft")){ NBTTagCompound rctag = new NBTTagCompound(); rctag.setBoolean("locked", BitUtil.getBit(this.dataWatcher.getWatchableObjectByte(3), 1)); if(this.charge!=null) this.charge.writeToNBT(rctag); String emblem = this.dataWatcher.getWatchableObjectString(5); if(emblem!=null && emblem!="") rctag.setString("emblem_id", emblem); else rctag.removeTag("emblem_id"); tag.setTag("railcraft", rctag); } nbt.setTag("advcart", tag); } public void readEntityFromNBT(NBTTagCompound nbt){ super.readEntityFromNBT(nbt); if(nbt.hasKey("advcart")){ NBTTagCompound tag = (NBTTagCompound) nbt.getTag("advcart"); if(tag.hasKey("enginespeed")) this.dataWatcher.updateObject(4, (float)tag.getDouble("enginespeed")); if(tag.hasKey("brake")) this.dataWatcher.updateObject(3, BitUtil.setBit(tag.getBoolean("brake"), this.dataWatcher.getWatchableObjectByte(3), 0)); if(tag.hasKey("railcraft") && Loader.isModLoaded("Railcraft")){ NBTTagCompound rctag = tag.getCompoundTag("railcraft"); this.dataWatcher.updateObject(3, BitUtil.setBit(rctag.getBoolean("locked"), this.dataWatcher.getWatchableObjectByte(3), 1)); if(this.charge!=null) this.charge.readFromNBT(rctag); if(rctag.hasKey("emblem_id")){ String id= rctag.getString("emblem_id"); this.dataWatcher.updateObject(5, (id==null)?"":id); } } } } @Override public void killMinecart(DamageSource p_94095_1_) { this.setDead(); ItemStack itemstack = this.getCartItem(); if (this.func_95999_t() != null) { itemstack.setStackDisplayName(this.func_95999_t()); } this.entityDropItem(itemstack, 0.0F); } @Override public int getMinecartType() { return -1; } public boolean onRail() { int x = MathHelper.floor_double(this.posX); int y = MathHelper.floor_double(this.posY); int z = MathHelper.floor_double(this.posZ); return BlockRailBase.func_150049_b_(this.worldObj, x, y, z); } public void onUpdate() { super.onUpdate(); if (this.worldObj.isRemote) return; if(charge!=null && Loader.isModLoaded("Railcraft")){ this.charge.tick(); double mv = this.addEnergy(this.charge.getCharge() * Settings.OC_IC2PWR, true); //Get max. energy we can load to the node mv = Math.min(mv, Settings.ComputerCartETrackLoad * Settings.OC_IC2PWR); //Check if the movable energy is higher than the limit. mv = this.charge.removeCharge(mv / Settings.OC_IC2PWR) * Settings.OC_IC2PWR; //Remove the charge from the buffer this.addEnergy(mv , false); //Add the removed energy to the node network } } @Override protected void func_145821_a(int trackX, int trackY, int trackZ, double maxSpeed, double slopeAdjustement, Block trackBlock, int trackMeta) { super.func_145821_a(trackX, trackY, trackZ, maxSpeed, slopeAdjustement, trackBlock, trackMeta); if (this.worldObj.isRemote) return; if(charge!=null && Loader.isModLoaded("Railcraft")){ this.charge.tickOnTrack(trackX, trackY, trackZ); } } protected void applyDrag() { if(!(BitUtil.getBit(this.dataWatcher.getWatchableObjectByte(3), 0) || BitUtil.getBit(this.dataWatcher.getWatchableObjectByte(3), 1))){ this.motionX *= 0.9699999785423279D; this.motionY *= 0.0D; this.motionZ *= 0.9699999785423279D; if(this.dataWatcher.getWatchableObjectFloat(4)!=0){ double yaw = this.rotationYaw * Math.PI / 180.0; this.motionX += Math.cos(yaw) * 10; this.motionZ += Math.sin(yaw) * 10; double nMotionX = Math.min( Math.abs(this.motionX) , this.dataWatcher.getWatchableObjectFloat(4)); double nMotionZ = Math.min( Math.abs(this.motionZ) , this.dataWatcher.getWatchableObjectFloat(4)); if(this.motionX < 0) this.motionX = - nMotionX; else this.motionX = nMotionX; if(this.motionZ < 0) this.motionZ = - nMotionZ; else this.motionZ = nMotionZ; } //Stop the cart if there is no speed. (below 0.0001 there are only sounds and no movement) if(Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ) < 0.0001){ this.motionX = 0; this.motionZ = 0; } } else if(!BitUtil.getBit(this.dataWatcher.getWatchableObjectByte(3), 1)){ this.motionX = 0; this.motionZ = 0; this.setPosition(this.lastTickPosX, this.posY, this.lastTickPosZ); // Fix: Bug on Booster Tracks (Reset Position) } } public double getSpeed(){ return Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ); } public AxisAlignedBB getBoundingBox() { if(Loader.isModLoaded("Railcraft") && Settings.GeneralFixCartBox) //The Railcraft collision handler breaks some things return super.getBoundingBox(); return this.getCollisionBox(this); } public boolean canBePushed() { return (!BitUtil.getBit(this.dataWatcher.getWatchableObjectByte(3),0) || !onRail()); } protected abstract double addEnergy(double amount, boolean simulate); /*-------Railcraft-------*/ public void lockdown(boolean lock){ if(lock != BitUtil.getBit(this.dataWatcher.getWatchableObjectByte(3), 1)) this.dataWatcher.updateObject(3, BitUtil.setBit(lock, this.dataWatcher.getWatchableObjectByte(3), 1)); } @Override public boolean canExtractEnergy() { return false; } @Override public boolean canInjectEnergy() { return false; } @Override public double extractEnergy(Object arg0, double arg1, int arg2, boolean arg3, boolean arg4, boolean arg5) { return 0; } @Override public int getCapacity() { return (int) this.charge.getCapacity(); } @Override public double getEnergy() { return charge.getCharge(); } @Override public int getTier() { return 1; } @Override public int getTransferLimit() { return (int)(Settings.ComputerCartETrackLoad * 1.1); } @Override public double injectEnergy(Object arg0, double arg1, int arg2, boolean arg3, boolean arg4, boolean arg5) { return 0; } @Override public ChargeHandler getChargeHandler() { return this.charge; } public boolean setEmblem(ItemStack stack){ if(!Loader.isModLoaded("Railcraft")) return false; return setEmblem(EmblemToolsServer.getEmblemIdentifier(stack)); } public boolean setEmblem(String emblem){ if(!Loader.isModLoaded("Railcraft")) return false; if(emblem==this.dataWatcher.getWatchableObjectString(5)) return false; if(emblem==null) emblem=""; this.dataWatcher.updateObject(5, emblem); return true; } public String getEmblem(){ if(!Loader.isModLoaded("Railcraft")) return null; return this.dataWatcher.getWatchableObjectString(5); } @Optional.Method(modid="Railcraft") public ResourceLocation getEmblemIcon(){ String id = this.dataWatcher.getWatchableObjectString(5); if(id==null || id.length()<1) return null; return EmblemToolsClient.packageManager.getEmblemTextureLocation(id); } }