Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public class TrackingList<T> extends AbstractList<T> {
- public TrackingList(List<T> parent) {
- this.parent = parent;
- added.addAll(parent);
- }
- @Override
- public T get(int index) {
- return parent.get(index);
- }
- @Override
- public int size() {
- return parent.size();
- }
- @Override
- public T set(int index, T element) {
- added.add(element);
- T ret = parent.set(index, element);
- if (ret != null) removed.add(ret);
- return ret;
- }
- @Override
- public void add(int index, T element) {
- parent.add(index, element);
- added.add(element);
- }
- @Override
- public T remove(int index) {
- T ret = parent.remove(index);
- if (ret != null) removed.add(ret);
- return ret;
- }
- public List<T> getAdded() {
- return added;
- }
- public List<T> getRemoved() {
- return removed;
- }
- private final List<T> parent;
- private final List<T> added = new ArrayList<T>();
- private final List<T> removed = new ArrayList<T>();
- }
- public class MainLogic {
- public static void onWorldTickEnd(World world) {
- if (world == null) throw new NullPointerException("tick for null world");
- WorldData worldData = getWorldData(world);
- // remove delegates for removed tes
- for (TileEntity te : worldData.trackingList.getRemoved()) {
- TileEntityDelegate delegate = worldData.enetDelegates.remove(te);
- if (delegate != null) {
- MinecraftForge.EVENT_BUS.post(new EnergyTileUnloadEvent(delegate));
- }
- }
- worldData.trackingList.getRemoved().clear();
- // create new delegates from pending tes
- for (TileEntity te : worldData.pendingEnetDelegates) {
- if (te.getWorldObj() == world &&
- EnergyNet.instance.getTileEntity(world, te.xCoord, te.yCoord, te.zCoord) == null) {
- TileEntityDelegate enetDelegate = RfBlockDelegate.create(te);
- if (enetDelegate == null) enetDelegate = ChargeBlockDelegate.create(te);
- if (enetDelegate != null) {
- TileEntityDelegate prev = worldData.enetDelegates.put(te, enetDelegate);
- assert prev == null;
- MinecraftForge.EVENT_BUS.post(new EnergyTileLoadEvent(enetDelegate));
- }
- }
- }
- worldData.pendingEnetDelegates.clear();
- // fill pending tes from added tes
- for (TileEntity te : worldData.trackingList.getAdded()) {
- if (RfBlockDelegate.isApplicable(te) ||
- ChargeBlockDelegate.isApplicable(te)) {
- if (EnergyNet.instance.getTileEntity(world, te.xCoord, te.yCoord, te.zCoord) == null) {
- worldData.pendingEnetDelegates.add(te);
- }
- }
- }
- worldData.trackingList.getAdded().clear();
- // tick delegates
- for (TileEntityDelegate delegate : worldData.enetDelegates.values()) {
- delegate.tick();
- }
- }
- protected static void setTrackingList(World world, TrackingList<TileEntity> tl) {
- getWorldData(world).trackingList = tl;
- }
- protected static void onWorldUnload(World world) {
- worldData.remove(world);
- }
- private static WorldData getWorldData(World world) {
- WorldData ret = worldData.get(world);
- if (ret == null) {
- ret = new WorldData();
- worldData.put(world, ret);
- }
- return ret;
- }
- private static class WorldData {
- final Map<TileEntity, TileEntityDelegate> enetDelegates = new HashMap<TileEntity, TileEntityDelegate>();
- final List<TileEntity> pendingEnetDelegates = new ArrayList<TileEntity>();
- TrackingList<TileEntity> trackingList;
- }
- private static final Map<World, WorldData> worldData = new WeakHashMap<World, WorldData>();
- }
- public class EventCallback {
- public static void load() {
- if (EnetBridge.getEnableTileEntityAdaption() &&
- (EnetBridge.hasRf() || EnetBridge.hasCharge())) {
- EventCallback cb = new EventCallback();
- FMLCommonHandler.instance().bus().register(cb);
- MinecraftForge.EVENT_BUS.register(cb);
- }
- }
- private EventCallback() {
- }
- @SubscribeEvent(priority = EventPriority.HIGH)
- public void onWorldTick(TickEvent.WorldTickEvent event) {
- if (event.phase != Phase.END) return;
- MainLogic.onWorldTickEnd(event.world);
- }
- @SubscribeEvent
- public void onWorldLoad(WorldEvent.Load event) {
- if (FMLCommonHandler.instance().getEffectiveSide().isServer()) {
- @SuppressWarnings("unchecked")
- TrackingList<TileEntity> tl = new TrackingList<TileEntity>(event.world.loadedTileEntityList);
- event.world.loadedTileEntityList = tl;
- MainLogic.setTrackingList(event.world, tl);
- }
- }
- @SubscribeEvent
- public void onWorldUnload(WorldEvent.Unload event) {
- MainLogic.onWorldUnload(event.world);
- }
- }
- public abstract class TileEntityDelegate extends TileEntity implements IEnergySink, IEnergySource {
- public TileEntityDelegate(TileEntity parent) {
- worldObj = parent.getWorldObj();
- xCoord = parent.xCoord;
- yCoord = parent.yCoord;
- zCoord = parent.zCoord;
- }
- public abstract void tick();
- @Override
- public int getSinkTier() {
- return Integer.MAX_VALUE;
- }
- @Override
- public int getSourceTier() {
- double energy = getOfferedEnergy();
- return energy > 0 ? EnergyNet.instance.getTierFromPower(energy) : 1;
- }
- }
- public class RfItemHandler implements IBackupElectricItemManager {
- public static boolean load() {
- try {
- ElectricItem.registerBackupManager(new RfItemHandler());
- return true;
- } catch (Exception e) {
- EnetBridge.log.warn("RF item handler init error: {}.", e.getMessage());
- return false;
- }
- }
- private RfItemHandler() {
- }
- @Override
- public boolean use(ItemStack stack, double amount, EntityLivingBase entity) {
- return ElectricItem.rawManager.use(stack, amount, entity);
- }
- @Override
- public String getToolTip(ItemStack stack) {
- return null;
- }
- @Override
- public double getCharge(ItemStack stack) {
- IEnergyContainerItem item = (IEnergyContainerItem) stack.getItem();
- return item.getEnergyStored(stack) / EnetBridge.getEuPerRf();
- }
- @Override
- public double discharge(ItemStack stack, double amount, int tier, boolean ignoreTransferLimit, boolean externally, boolean simulate) {
- int rf = (int) (amount / EnetBridge.getEuPerRf());
- if (rf <= 0) return 0;
- IEnergyContainerItem item = (IEnergyContainerItem) stack.getItem();
- int ret = item.extractEnergy(stack, rf, simulate);
- return Math.min(ret * EnetBridge.getEuPerRf(), amount);
- }
- @Override
- public void chargeFromArmor(ItemStack stack, EntityLivingBase entity) {
- ElectricItem.rawManager.chargeFromArmor(stack, entity);
- }
- @Override
- public double charge(ItemStack stack, double amount, int tier, boolean ignoreTransferLimit, boolean simulate) {
- int rf = (int) (amount * EnetBridge.getRfPerEu());
- if (rf <= 0) return 0;
- IEnergyContainerItem item = (IEnergyContainerItem) stack.getItem();
- double ret = item.receiveEnergy(stack, rf, simulate);
- return Math.min(ret / EnetBridge.getRfPerEu(), amount);
- }
- @Override
- public boolean canUse(ItemStack stack, double amount) {
- return ElectricItem.rawManager.canUse(stack, amount);
- }
- @Override
- public boolean handles(ItemStack stack) {
- return stack.getItem() instanceof IEnergyContainerItem;
- }
- }
- public class RfBlockDelegate extends TileEntityDelegate {
- public static TileEntityDelegate create(TileEntity te) {
- if (!isApplicable(te)) return null;
- try {
- return new RfBlockDelegate(te);
- } catch (Exception e) {
- EnetBridge.log.warn("RF delegate init error: {}.", e.getMessage());
- return null;
- }
- }
- public static boolean isApplicable(TileEntity te) {
- return EnetBridge.hasRf() && (te instanceof IEnergyProvider || te instanceof IEnergyReceiver);
- }
- private RfBlockDelegate(TileEntity base) {
- super(base);
- this.base = (IEnergyConnection) base;
- if (base instanceof IEnergyProvider) {
- this.provider = (IEnergyProvider) base;
- } else {
- this.provider = null;
- }
- if (base instanceof IEnergyReceiver) {
- this.receiver = (IEnergyReceiver) base;
- } else {
- this.receiver = null;
- }
- updateDirs(false);
- }
- @Override
- public void tick() {
- if (!faulty && updateDirs(true)) {
- // refresh connectivity
- MinecraftForge.EVENT_BUS.post(new EnergyTileUnloadEvent(this));
- updateDirs(false);
- MinecraftForge.EVENT_BUS.post(new EnergyTileLoadEvent(this));
- }
- }
- @Override
- public boolean acceptsEnergyFrom(TileEntity emitter, ForgeDirection direction) {
- return !faulty && receiver != null && sinkDirs.contains(direction);
- }
- @Override
- public boolean emitsEnergyTo(TileEntity receiver, ForgeDirection direction) {
- return !faulty && provider != null && sourceDirs.contains(direction);
- }
- @Override
- public double getDemandedEnergy() {
- if (faulty) return 0;
- if (receiver == null) return 0;
- int max = 0;
- for (ForgeDirection dir : sinkDirs) {
- int amount = receiver.receiveEnergy(dir, Integer.MAX_VALUE, true);
- if (amount > max) max = amount;
- }
- return max * 1. / EnetBridge.getRfPerEu();
- }
- @Override
- public double getOfferedEnergy() {
- if (faulty) return 0;
- if (provider == null) return 0;
- int max = 0;
- for (ForgeDirection dir : sourceDirs) {
- int amount = provider.extractEnergy(dir, Integer.MAX_VALUE, true);
- if (amount > max) max = amount;
- }
- return max * EnetBridge.getEuPerRf();
- }
- @Override
- public double injectEnergy(ForgeDirection directionFrom, double amount, double voltage) {
- if (receiver == null) return amount;
- amount *= EnetBridge.getRfPerEu();
- int iAmount = (int) amount;
- if (iAmount <= 0) return amount;
- amount -= iAmount;
- if (directionFrom != ForgeDirection.UNKNOWN) {
- iAmount -= receiver.receiveEnergy(directionFrom, iAmount, false);
- }
- for (ForgeDirection dir : sinkDirs) {
- if (iAmount <= 0) break;
- iAmount -= receiver.receiveEnergy(dir, iAmount, false);
- }
- return (amount + iAmount) * 1. / EnetBridge.getRfPerEu();
- }
- @Override
- public void drawEnergy(double amount) {
- if (provider != null) {
- for (ForgeDirection dir : sourceDirs) {
- amount -= provider.extractEnergy(dir, (int) Math.ceil(amount / EnetBridge.getEuPerRf()), false) * EnetBridge.getEuPerRf();
- if (amount <= 0) break;
- }
- }
- if (amount > 0) {
- EnetBridge.log.warn("Can't draw the full amount from {}, {} left over, disabling the delegate.", base, amount);
- faulty = true;
- }
- }
- private boolean updateDirs(boolean simulate) {
- EnumSet<ForgeDirection> newSinkdirs = EnumSet.noneOf(ForgeDirection.class);
- EnumSet<ForgeDirection> newSourcedirs = EnumSet.noneOf(ForgeDirection.class);
- // probe directions if they are connectable and can source or sink energy
- for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) {
- if (!base.canConnectEnergy(dir)) continue;
- if (receiver != null && EnetBridge.getRfPerEu() > 0) { // sink
- if (receiver.getEnergyStored(dir) >= receiver.getMaxEnergyStored(dir) || // be optimistic if we can't check
- receiver.receiveEnergy(dir, Integer.MAX_VALUE, true) > 0) {
- newSinkdirs.add(dir);
- }
- }
- if (provider != null && EnetBridge.getEuPerRf() > 0) { // source
- if (provider.getEnergyStored(dir) <= 0 || // be optimistic if we can't check
- provider.extractEnergy(dir, Integer.MAX_VALUE, true) > 0) {
- newSourcedirs.add(dir);
- }
- }
- }
- if (sinkDirs.equals(newSinkdirs) && sourceDirs.equals(newSourcedirs)) {
- return false;
- } else {
- if (!simulate) {
- sinkDirs.clear();
- sinkDirs.addAll(newSinkdirs);
- sourceDirs.clear();
- sourceDirs.addAll(newSourcedirs);
- }
- //EnetBridge.log.debug("Detected new dirs for {}: {}, {}.", base, sinkDirs, sourceDirs);
- return true;
- }
- }
- private final IEnergyConnection base;
- private final IEnergyProvider provider;
- private final IEnergyReceiver receiver;
- protected boolean faulty = false;
- protected final Set<ForgeDirection> sinkDirs = EnumSet.noneOf(ForgeDirection.class);
- protected final Set<ForgeDirection> sourceDirs = EnumSet.noneOf(ForgeDirection.class);
- }
- public class ChargeBlockDelegate extends TileEntityDelegate {
- public static TileEntityDelegate create(TileEntity te) {
- if (!isApplicable(te)) return null;
- try {
- return new ChargeBlockDelegate(te);
- } catch (Exception e) {
- EnetBridge.log.warn("Charge delegate init error: {}.", e.getMessage());
- return null;
- }
- }
- public static boolean isApplicable(TileEntity te) {
- return EnetBridge.hasCharge() && te instanceof IChargeConductor;
- }
- private ChargeBlockDelegate(TileEntity te) {
- super(te);
- this.base = (IChargeConductor) te;
- }
- @Override
- public void tick() {
- }
- @Override
- public boolean acceptsEnergyFrom(TileEntity emitter, ForgeDirection direction) {
- return !faulty;
- }
- @Override
- public boolean emitsEnergyTo(TileEntity receiver, ForgeDirection direction) {
- return !faulty;
- }
- @Override
- public double getDemandedEnergy() {
- if (faulty) return 0;
- return Math.max(0, EnetBridge.getTargetCharge() - base.getCharge().getValue()) * 1. / EnetBridge.getChargePerEu();
- }
- @Override
- public double getOfferedEnergy() {
- if (faulty) return 0;
- return Math.max(0, base.getCharge().getValue() - EnetBridge.getTargetCharge()) * EnetBridge.getEuPerCharge();
- }
- @Override
- public double injectEnergy(ForgeDirection directionFrom, double amount, double voltage) {
- amount *= EnetBridge.getChargePerEu();
- int iAmount = (int) amount;
- if (iAmount <= 0) return amount;
- amount -= iAmount;
- base.getCharge().addValue(iAmount);
- return amount * 1. / EnetBridge.getChargePerEu();
- }
- @Override
- public void drawEnergy(double amount) {
- amount -= base.getCharge().deplete((int) Math.ceil(amount / EnetBridge.getEuPerCharge())) * EnetBridge.getEuPerCharge();
- if (amount > 0) {
- EnetBridge.log.warn("Can't draw the full amount from {}, {} left over, disabling the delegate.", base, amount);
- faulty = true;
- }
- }
- private final IChargeConductor base;
- protected boolean faulty = false;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement