package mods.ocminecart.common.component; import cpw.mods.fml.common.Loader; import li.cil.oc.api.Network; import li.cil.oc.api.machine.Arguments; import li.cil.oc.api.machine.Callback; import li.cil.oc.api.machine.Context; import li.cil.oc.api.network.Connector; import li.cil.oc.api.network.Visibility; import li.cil.oc.api.prefab.ManagedEnvironment; import mods.ocminecart.Settings; import mods.ocminecart.common.minecart.IComputerCart; import mods.ocminecart.interaction.railcraft.RailcraftUtils; import mods.railcraft.api.carts.CartTools; import mods.railcraft.api.carts.ILinkageManager; import net.minecraft.entity.item.EntityMinecart; import java.util.HashMap; public class LinkingUpgrade extends ManagedEnvironment{ private IComputerCart cart; public LinkingUpgrade (IComputerCart cart){ super(); this.cart=cart; this.setNode(Network.newNode(this, Visibility.Network).withComponent("cartlinking").create()); } @Callback(doc = "function([index:number]):boolean,[string] -- Unlink cart (with the index) behind this cart") public Object[] unlinkBack(Context ctx, Arguments args){ checkRailcraft(); int cindex = args.optInteger(0, 1); if(!hasEnergy(Settings.LinkingUnlinkCost)) return new Object[]{false, "not enougth energy"}; Object[] res = unlink0(cindex,false); if(res[0].equals(true))takeEnergy(Settings.LinkingUnlinkCost); ctx.pause(Settings.LinkingUnlinkDelay); return res; } @Callback(doc = "function([index:number]):boolean,[string] -- Unlink cart (with the index) in front of this cart") public Object[] unlinkFront(Context ctx, Arguments args){ checkRailcraft(); int cindex = args.optInteger(0, 1); if(!hasEnergy(Settings.LinkingUnlinkCost)) return new Object[]{false, "not enougth energy"}; Object[] res = unlink0(cindex,true); if(res[0].equals(true))takeEnergy(Settings.LinkingUnlinkCost); ctx.pause(Settings.LinkingUnlinkDelay); return res; } @Callback(doc = "function():number -- Link a cart behind the chain") public Object[] linkBack(Context ctx, Arguments args){ checkRailcraft(); if(!hasEnergy(Settings.LinkingLinkCost)) return new Object[]{false, "not enougth energy"}; Object[] res = link0(false); if(res[0].equals(true))takeEnergy(Settings.LinkingLinkCost); ctx.pause(Settings.LinkingLinkDelay); return res; } @Callback(doc = "function():number -- Link a cart in front of the chain") public Object[] linkFront(Context ctx, Arguments args){ checkRailcraft(); if(!hasEnergy(Settings.LinkingLinkCost)) return new Object[]{false, "not enougth energy"}; Object[] res = link0(true); if(res[0].equals(true))takeEnergy(Settings.LinkingLinkCost); ctx.pause(Settings.LinkingLinkDelay); return res; } @Callback(doc = "function():number -- Count carts behind this cart.") public Object[] countBack(Context ctx, Arguments args){ checkRailcraft(); return count0(false); } @Callback(doc = "function():number -- Count carts in front of this cart.") public Object[] countFront(Context ctx, Arguments args){ checkRailcraft(); return count0(true); } private boolean hasEnergy(double e){ if(!(cart.node()instanceof Connector)) return false; Connector c = ((Connector)cart.node()); return c.globalBuffer()>=e; } private void takeEnergy(double e){ if(!(cart.node()instanceof Connector)) return; Connector c = ((Connector)cart.node()); c.changeBuffer(-e); } private Object[] link0(boolean front){ EntityMinecart ccart = RailcraftUtils.getConnectedCartSide((EntityMinecart)cart, front); HashMap<Integer, EntityMinecart> map = RailcraftUtils.sortCarts((EntityMinecart) cart); int dir = RailcraftUtils.getCartCountDir(map, ccart); int count = RailcraftUtils.countCarts((EntityMinecart) this.cart, ccart)-1; EntityMinecart linkcart1 = map.get(dir*count); if(linkcart1==null) return new Object[]{false, "internal error"}; double dyaw = 0D; if(!linkcart1.equals(cart)){ if(RailcraftUtils.isCartInField(linkcart1, map.get(dir*(count-1)), 179, 0)){ //If the cart looks to the row, look at the other side dyaw+=180D; } } else if(!front)dyaw+=180D; while(dyaw>=360D) dyaw-=360D; while(dyaw<0D) dyaw+=360D; EntityMinecart linkcart2 = RailcraftUtils.findLinkableCart(linkcart1, dyaw); if(linkcart2==null) return new Object[]{false, "No cart in range"}; ILinkageManager link = CartTools.linkageManager; boolean done = link.createLink(linkcart1, linkcart2); if(!done) return new Object[]{false, "No cart in range"}; return new Object[]{true}; } private Object[] count0(boolean front){ int count; EntityMinecart c = RailcraftUtils.getConnectedCartSide((EntityMinecart)cart, front); if(c!=null) count=RailcraftUtils.countCarts((EntityMinecart) cart,c)-1; else count=0; return new Object[]{count}; } private Object[] unlink0(int cindex, boolean front){ if(cindex<1) throw new IllegalArgumentException("invalid index"); EntityMinecart c = RailcraftUtils.getConnectedCartSide((EntityMinecart)cart, front); if(c==null) return new Object[]{false, "cart not found"}; HashMap<Integer, EntityMinecart> map = RailcraftUtils.sortCarts((EntityMinecart) cart); int dir = RailcraftUtils.getCartCountDir(map, c); if(!map.containsKey((cindex-1)*dir) || !map.containsKey(cindex*dir)) return new Object[]{false, "cart not found"}; ILinkageManager link = CartTools.linkageManager; link.breakLink(map.get(cindex*dir), map.get((cindex-1)*dir)); return new Object[]{true}; } private void checkRailcraft(){ if(!Loader.isModLoaded("Railcraft")) throw new IllegalArgumentException("Railcraft is not installed."); } }