package gtPlusPlus.xmod.gregtech.common.helpers; import static gregtech.api.GregTechAPI.mEUtoRF; import static gregtech.api.enums.Mods.Baubles; import static gregtech.api.enums.Mods.COFHCore; import java.util.HashMap; import java.util.Map; import java.util.UUID; import javax.annotation.Nonnull; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.InventoryPlayer; import net.minecraft.inventory.IInventory; import net.minecraft.item.ItemStack; import baubles.api.BaublesApi; import cofh.api.energy.IEnergyContainerItem; import cpw.mods.fml.common.eventhandler.EventPriority; import cpw.mods.fml.common.eventhandler.SubscribeEvent; import cpw.mods.fml.common.gameevent.TickEvent.ServerTickEvent; import gregtech.api.enums.GTValues; import gregtech.api.util.GTModHandler; import gregtech.common.items.MetaGeneratedItem01; import gregtech.common.items.MetaGeneratedItem02; import gregtech.common.items.MetaGeneratedItem03; import gregtech.common.items.MetaGeneratedTool01; import gtPlusPlus.api.objects.data.Pair; import gtPlusPlus.api.objects.minecraft.BlockPos; import gtPlusPlus.core.util.Utils; import gtPlusPlus.core.util.math.MathUtils; import gtPlusPlus.core.util.minecraft.NBTUtils; import gtPlusPlus.core.util.minecraft.PlayerUtils; import gtPlusPlus.xmod.gregtech.common.tileentities.machines.basic.MTEWirelessCharger; import ic2.api.item.ElectricItem; import ic2.api.item.IElectricItem; public class ChargingHelper { private static final Map> mValidPlayers = new HashMap<>(); protected static Map mChargerMap = new HashMap<>(); private int mTickTimer = 0; private static final int mTickMultiplier = 20; @SubscribeEvent(priority = EventPriority.HIGHEST) public void onServerTick(ServerTickEvent event) { if (++mTickTimer % mTickMultiplier == 0) { if (Utils.isServer()) { for (EntityPlayer mPlayerMan : PlayerUtils.getOnlinePlayers()) { doPlayerChargeTick(mPlayerMan); } } } } @SuppressWarnings("unused") private void doPlayerChargeTick(EntityPlayer mPlayerMan) { try { long mVoltage; long mEuStored; if (!mChargerMap.isEmpty() && mValidPlayers.containsKey(mPlayerMan.getDisplayName())) { InventoryPlayer mPlayerInventory = mPlayerMan.inventory; ItemStack[] mArmourContents = mPlayerInventory.armorInventory.clone(); ItemStack[] mInventoryContents = mPlayerInventory.mainInventory.clone(); ItemStack[] baubleSlots = null; if (Baubles.isModLoaded()) { IInventory baubleInv = BaublesApi.getBaubles(mPlayerMan); if (baubleInv != null) { baubleSlots = new ItemStack[baubleInv.getSizeInventory()]; for (int i = 0; i < baubleInv.getSizeInventory(); i++) { baubleSlots[i] = baubleInv.getStackInSlot(i); } } } for (MTEWirelessCharger mEntityTemp : mChargerMap.values()) { if (mEntityTemp != null) { if (mEntityTemp.getBaseMetaTileEntity() == null || !mEntityTemp.getBaseMetaTileEntity() .isAllowedToWork()) continue; if (mPlayerMan.getEntityWorld().provider.dimensionId == mEntityTemp.getDimensionID()) { mVoltage = mEntityTemp.maxEUInput(); mEuStored = mEntityTemp.getEUVar(); if (mVoltage > 0 && mEuStored >= mVoltage) { Map LR = mEntityTemp.getLongRangeMap(); Map LO = mEntityTemp.getLocalMap(); long mStartingEu = mEntityTemp.getEUVar(); if (canCharge(mEntityTemp, mPlayerMan, LR, LO)) { chargeItems(mEntityTemp, mArmourContents); chargeItems(mEntityTemp, mInventoryContents); chargeItems(mEntityTemp, baubleSlots); } if (mStartingEu - mEntityTemp.getEUVar() <= 0) { long mMaxDistance; if (mEntityTemp.getMode() == 0) { mMaxDistance = (4 * GTValues.V[mEntityTemp.getTier()]); } else if (mEntityTemp.getMode() == 1) { mMaxDistance = (mEntityTemp.getTier() * 10L); } else { mMaxDistance = (4 * GTValues.V[mEntityTemp.getTier()] / 2); } double mDistance = calculateDistance(mEntityTemp, mPlayerMan); long mVoltageCost = MathUtils.findPercentageOfInt(mMaxDistance, (float) mDistance); if (mVoltageCost > 0) { if (mVoltageCost > mEntityTemp.maxEUInput()) { mEntityTemp.setEUVar((mEntityTemp.getEUVar() - mEntityTemp.maxEUInput())); } else { mEntityTemp.setEUVar((mEntityTemp.getEUVar() - mVoltageCost)); } } } } } } } } } catch (Throwable t) { if (!mChargerMap.isEmpty()) { for (BlockPos aPos : mChargerMap.keySet()) { MTEWirelessCharger r = mChargerMap.get(aPos); if (r == null || r.getBaseMetaTileEntity() .isInvalidTileEntity()) { mChargerMap.remove(aPos); } } } } } public static MTEWirelessCharger getEntry(BlockPos mPos) { return mChargerMap.get(mPos); } public static boolean addEntry(BlockPos mPos, MTEWirelessCharger mEntity) { if (mEntity == null) { return false; } mChargerMap.put(mPos, mEntity); return true; } public static boolean removeEntry(BlockPos mPos, MTEWirelessCharger mEntity) { if (mEntity == null) { return false; } if (mChargerMap.containsKey(mPos)) { return mChargerMap.remove(mPos, mEntity); } else { return false; } } public static boolean addValidPlayer(EntityPlayer mPlayer, MTEWirelessCharger mEntity) { if (mEntity == null) { return false; } if (mValidPlayers.containsKey(mPlayer.getDisplayName())) { return false; } else { Pair mEntry = new Pair<>(mEntity, (byte) mEntity.getMode()); return mValidPlayers.put(mPlayer.getDisplayName(), mEntry) == null; } } public static boolean removeValidPlayer(EntityPlayer mPlayer, MTEWirelessCharger mEntity) { if (mEntity == null) { return false; } if (mValidPlayers.containsKey(mPlayer.getDisplayName())) { Pair mEntry = new Pair<>(mEntity, (byte) mEntity.getMode()); return mValidPlayers.remove(mPlayer.getDisplayName(), mEntry); } else { return false; } } private boolean canCharge(MTEWirelessCharger charger, EntityPlayer chargeablePlayer, Map longRangeChargers, Map shortRangeChargers) { if (charger.getMode() == 0) { return !longRangeChargers.isEmpty() && longRangeChargers.containsKey(chargeablePlayer.getDisplayName()); } else if (charger.getMode() == 1) { return !shortRangeChargers.isEmpty() && shortRangeChargers.containsKey(chargeablePlayer.getDisplayName()); } else { if (!longRangeChargers.isEmpty() && longRangeChargers.containsKey(chargeablePlayer.getDisplayName())) { return true; } return !shortRangeChargers.isEmpty() && shortRangeChargers.containsKey(chargeablePlayer.getDisplayName()); } } private double calculateDistance(MTEWirelessCharger mEntityTemp, EntityPlayer mPlayerMan) { if (mEntityTemp == null || mPlayerMan == null) { return 0; } return mEntityTemp.getDistanceBetweenTwoPositions( mEntityTemp.getTileEntityPosition(), mEntityTemp.getPositionOfEntity(mPlayerMan)); } private void chargeItems(@Nonnull MTEWirelessCharger mEntity, ItemStack[] mItems) { if (mItems == null || mItems.length == 0) { return; } chargeItemsEx(mEntity, mItems); } private void chargeItemsEx(@Nonnull MTEWirelessCharger mEntity, ItemStack[] mItems) { // Bad Inventory if (mItems == null || mItems.length == 0) { return; } // Set Variables to Charge final long mVoltage = mEntity.maxEUInput(); long mEuStored = mEntity.getEUVar(); // For Inventory Contents for (ItemStack mTemp : mItems) { // Is item Electrical if (isItemValid(mTemp)) { // Transfer Limit double mItemEuTLimit = ((IElectricItem) mTemp.getItem()).getTransferLimit(mTemp); // Check if Tile has more or equal EU to what can be transferred into the item. if (mEuStored >= mItemEuTLimit) { double mItemMaxCharge = ((IElectricItem) mTemp.getItem()).getMaxCharge(mTemp); double mitemCurrentCharge = ElectricItem.manager.getCharge(mTemp); if (mitemCurrentCharge >= mItemMaxCharge) { continue; } // Try to get charge direct from NBT for GT and IC2 stacks if (mTemp.getItem() instanceof MetaGeneratedTool01 || mTemp.getItem() instanceof MetaGeneratedItem01 || mTemp.getItem() instanceof MetaGeneratedItem02 || mTemp.getItem() instanceof MetaGeneratedItem03 || mTemp.getItem() .getClass() .getName() .equalsIgnoreCase(MetaGeneratedTool01.class.getName())) { if (!NBTUtils.hasKey(mTemp, "GT.ItemCharge")) { if (!mTemp.getDisplayName() .toLowerCase() .contains("battery")) { if (!GTModHandler.isElectricItem(mTemp)) { continue; } } else { mitemCurrentCharge = 0; } } else { mitemCurrentCharge = NBTUtils.getLong(mTemp, "GT.ItemCharge"); } } else if (mTemp.getItem() instanceof IElectricItem) { mitemCurrentCharge = NBTUtils.getLong(mTemp, "charge"); } double mVoltageIncrease; if (mItemEuTLimit >= mVoltage) { mVoltageIncrease = mVoltage; } else if (mItemEuTLimit < mVoltage) { mVoltageIncrease = mItemEuTLimit; } else { mVoltageIncrease = mItemEuTLimit; } int mMulti; if ((mitemCurrentCharge + (mVoltageIncrease * 20)) <= (mItemMaxCharge - (mVoltageIncrease * 20))) { mMulti = 20; } else if ((mitemCurrentCharge + (mVoltageIncrease * 10)) <= (mItemMaxCharge - (mVoltageIncrease * 10))) { mMulti = 10; } else if ((mitemCurrentCharge + (mVoltageIncrease * 5)) <= (mItemMaxCharge - (mVoltageIncrease * 5))) { mMulti = 5; } else { mMulti = 1; } int mMultiVoltage = (int) (mMulti * mVoltageIncrease); if ((mitemCurrentCharge + mMultiVoltage) <= mItemMaxCharge) { if (GTModHandler.chargeElectricItem(mTemp, mMultiVoltage, Integer.MAX_VALUE, true, false) > 0) { for (int i = 0; i < mMulti; i++) { ElectricItem.manager.charge(mTemp, mVoltageIncrease, Integer.MAX_VALUE, false, false); } } if (ElectricItem.manager.getCharge(mTemp) > mitemCurrentCharge) { mEntity.setEUVar(mEuStored - (mVoltage * mMulti)); mEuStored = mEntity.getEUVar(); } } // Try top up Item Chrage mitemCurrentCharge = ElectricItem.manager.getCharge(mTemp); if (mitemCurrentCharge < mItemMaxCharge && mitemCurrentCharge >= (mItemMaxCharge - mVoltage)) { int xDif = (int) (mItemMaxCharge - mitemCurrentCharge); if (GTModHandler.chargeElectricItem(mTemp, xDif, Integer.MAX_VALUE, true, false) >= 0) { if (ElectricItem.manager.getCharge(mTemp) >= mItemMaxCharge) { mEntity.setEUVar(mEntity.getEUVar() - (xDif)); mEuStored = mEntity.getEUVar(); } } } } } else if (isItemValidRF(mTemp)) { try { IEnergyContainerItem rfItem = (IEnergyContainerItem) mTemp.getItem(); if (rfItem != null) { long chargedPower = Math.min( rfItem.getMaxEnergyStored(mTemp) - rfItem.getEnergyStored(mTemp), mEntity.getEUVar() * mEUtoRF / 100L); chargedPower = rfItem.receiveEnergy( mTemp, chargedPower > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) chargedPower, false); chargedPower = chargedPower * 100L / mEUtoRF; mEntity.setEUVar(Math.max(mEntity.getEUVar() - chargedPower, 0)); mEuStored = mEntity.getEUVar(); } } catch (Exception ignored) { } } } } public static boolean isItemValid(final ItemStack itemstack) { if (itemstack == null) { return false; } if (GTModHandler.isElectricItem(itemstack)) { return true; } return itemstack.getItem() instanceof IElectricItem; } private static boolean isItemValidRF(final ItemStack itemStack) { return itemStack != null && COFHCore.isModLoaded() && itemStack.getItem() instanceof IEnergyContainerItem; } }