Search in sources :

Example 11 with IEnergyContainer

use of mekanism.api.energy.IEnergyContainer in project Mekanism by mekanism.

the class ItemSeismicReader method use.

@Nonnull
@Override
public ActionResult<ItemStack> use(World world, PlayerEntity player, @Nonnull Hand hand) {
    ItemStack stack = player.getItemInHand(hand);
    if (world.isClientSide) {
        return new ActionResult<>(ActionResultType.SUCCESS, stack);
    }
    if (!WorldUtils.isChunkVibrated(new ChunkPos(player.blockPosition()), player.level)) {
        player.sendMessage(MekanismUtils.logFormat(EnumColor.RED, MekanismLang.NO_VIBRATIONS), Util.NIL_UUID);
    } else {
        if (!player.isCreative()) {
            IEnergyContainer energyContainer = StorageUtils.getEnergyContainer(stack, 0);
            FloatingLong energyUsage = MekanismConfig.gear.seismicReaderEnergyUsage.get();
            if (energyContainer == null || energyContainer.extract(energyUsage, Action.SIMULATE, AutomationType.MANUAL).smallerThan(energyUsage)) {
                player.sendMessage(MekanismUtils.logFormat(EnumColor.RED, MekanismLang.NEEDS_ENERGY), Util.NIL_UUID);
                return new ActionResult<>(ActionResultType.SUCCESS, stack);
            }
            energyContainer.extract(energyUsage, Action.EXECUTE, AutomationType.MANUAL);
        }
        MekanismContainerTypes.SEISMIC_READER.tryOpenGui((ServerPlayerEntity) player, hand, stack);
    }
    return new ActionResult<>(ActionResultType.SUCCESS, stack);
}
Also used : FloatingLong(mekanism.api.math.FloatingLong) IEnergyContainer(mekanism.api.energy.IEnergyContainer) ActionResult(net.minecraft.util.ActionResult) ChunkPos(net.minecraft.util.math.ChunkPos) ItemStack(net.minecraft.item.ItemStack) Nonnull(javax.annotation.Nonnull)

Example 12 with IEnergyContainer

use of mekanism.api.energy.IEnergyContainer in project Mekanism by mekanism.

the class ItemAtomicDisassembler method getDestroySpeed.

@Override
public float getDestroySpeed(@Nonnull ItemStack stack, @Nonnull BlockState state) {
    IEnergyContainer energyContainer = StorageUtils.getEnergyContainer(stack, 0);
    if (energyContainer == null) {
        return 0;
    }
    // Use raw hardness to get the best guess of if it is zero or not
    FloatingLong energyRequired = getDestroyEnergy(stack, state.destroySpeed);
    FloatingLong energyAvailable = energyContainer.extract(energyRequired, Action.SIMULATE, AutomationType.MANUAL);
    if (energyAvailable.smallerThan(energyRequired)) {
        // If we can't extract all the energy we need to break it go at base speed reduced by how much we actually have available
        return DisassemblerMode.NORMAL.getEfficiency() * energyAvailable.divide(energyRequired).floatValue();
    }
    return getMode(stack).getEfficiency();
}
Also used : FloatingLong(mekanism.api.math.FloatingLong) IEnergyContainer(mekanism.api.energy.IEnergyContainer)

Example 13 with IEnergyContainer

use of mekanism.api.energy.IEnergyContainer in project Mekanism by mekanism.

the class ItemNetworkReader method useOn.

@Nonnull
@Override
public ActionResultType useOn(ItemUseContext context) {
    PlayerEntity player = context.getPlayer();
    World world = context.getLevel();
    if (!world.isClientSide && player != null) {
        BlockPos pos = context.getClickedPos();
        TileEntity tile = WorldUtils.getTileEntity(world, pos);
        if (tile != null) {
            if (!player.isCreative()) {
                FloatingLong energyPerUse = MekanismConfig.gear.networkReaderEnergyUsage.get();
                IEnergyContainer energyContainer = StorageUtils.getEnergyContainer(context.getItemInHand(), 0);
                if (energyContainer == null || energyContainer.extract(energyPerUse, Action.SIMULATE, AutomationType.MANUAL).smallerThan(energyPerUse)) {
                    return ActionResultType.FAIL;
                }
                energyContainer.extract(energyPerUse, Action.EXECUTE, AutomationType.MANUAL);
            }
            Direction opposite = context.getClickedFace().getOpposite();
            if (tile instanceof TileEntityTransmitter) {
                displayTransmitterInfo(player, ((TileEntityTransmitter) tile).getTransmitter(), tile, opposite);
            } else {
                Optional<IHeatHandler> heatHandler = CapabilityUtils.getCapability(tile, Capabilities.HEAT_HANDLER_CAPABILITY, opposite).resolve();
                if (heatHandler.isPresent()) {
                    IHeatHandler transfer = heatHandler.get();
                    displayBorder(player, MekanismLang.MEKANISM, true);
                    sendTemperature(player, transfer);
                    displayEndBorder(player);
                } else {
                    displayConnectedNetworks(player, world, pos);
                }
            }
            return ActionResultType.SUCCESS;
        } else if (player.isShiftKeyDown() && MekanismAPI.debug) {
            displayBorder(player, MekanismLang.DEBUG_TITLE, true);
            for (ITextComponent component : TransmitterNetworkRegistry.getInstance().toComponents()) {
                player.sendMessage(TextComponentUtil.build(EnumColor.DARK_GRAY, component), Util.NIL_UUID);
            }
            displayEndBorder(player);
        }
    }
    return ActionResultType.PASS;
}
Also used : TileEntity(net.minecraft.tileentity.TileEntity) FloatingLong(mekanism.api.math.FloatingLong) IEnergyContainer(mekanism.api.energy.IEnergyContainer) ITextComponent(net.minecraft.util.text.ITextComponent) BlockPos(net.minecraft.util.math.BlockPos) TileEntityTransmitter(mekanism.common.tile.transmitter.TileEntityTransmitter) World(net.minecraft.world.World) Direction(net.minecraft.util.Direction) PlayerEntity(net.minecraft.entity.player.PlayerEntity) IHeatHandler(mekanism.api.heat.IHeatHandler) Nonnull(javax.annotation.Nonnull)

Example 14 with IEnergyContainer

use of mekanism.api.energy.IEnergyContainer in project Mekanism by mekanism.

the class ModuleGeothermalGeneratorUnit method tickServer.

@Override
public void tickServer(IModule<ModuleGeothermalGeneratorUnit> module, PlayerEntity player) {
    IEnergyContainer energyContainer = module.getEnergyContainer();
    if (energyContainer != null && !energyContainer.getNeeded().isZero()) {
        double highestScaledDegrees = 0;
        double legHeight = player.isCrouching() ? 0.6 : 0.7;
        Map<Fluid, FluidInDetails> fluidsIn = MekanismUtils.getFluidsIn(player, bb -> new AxisAlignedBB(bb.minX, bb.minY, bb.minZ, bb.maxX, Math.min(bb.minY + legHeight, bb.maxY), bb.maxZ));
        for (Map.Entry<Fluid, FluidInDetails> entry : fluidsIn.entrySet()) {
            FluidInDetails details = entry.getValue();
            double height = details.getMaxHeight();
            if (height < 0.25) {
                // Skip fluids that we are barely submerged in
                continue;
            }
            double temperature = 0;
            List<BlockPos> positions = details.getPositions();
            for (BlockPos position : positions) {
                temperature += entry.getKey().getAttributes().getTemperature(player.level, position);
            }
            // Divide the temperature by how many positions there are in case there is a difference due to the position in the world
            // Strictly speaking we should take the height of the position into account for calculating the average as a "weighted"
            // average, but we don't worry about that as it is highly unlikely the positions will actually have different temperatures,
            // and it would add a bunch of complexity to the calculations to account for it
            temperature /= positions.size();
            if (temperature > HeatAPI.AMBIENT_TEMP) {
                // If the temperature is above the ambient temperature, calculate how many degrees above
                // and factor in how much of the legs are submerged
                double scaledDegrees = (temperature - HeatAPI.AMBIENT_TEMP) * height / legHeight;
                if (scaledDegrees > highestScaledDegrees) {
                    highestScaledDegrees = scaledDegrees;
                }
            }
        }
        if (highestScaledDegrees > 0 || player.isOnFire()) {
            // Note: We compare this against zero as we adjust against ambient before scaling
            if (highestScaledDegrees < 200 && player.isOnFire()) {
                // Treat fire as having a temperature of ~500K, this is on the cooler side of what fire tends to
                // be but should be good enough for factoring in how much a heat adapter would be able to transfer
                highestScaledDegrees = 200;
            }
            // Insert energy
            FloatingLong rate = MekanismGeneratorsConfig.gear.mekaSuitGeothermalChargingRate.get().multiply(module.getInstalledCount()).multiply(highestScaledDegrees);
            energyContainer.insert(rate, Action.EXECUTE, AutomationType.MANUAL);
        }
    }
}
Also used : AxisAlignedBB(net.minecraft.util.math.AxisAlignedBB) FloatingLong(mekanism.api.math.FloatingLong) IEnergyContainer(mekanism.api.energy.IEnergyContainer) FluidInDetails(mekanism.common.util.MekanismUtils.FluidInDetails) Fluid(net.minecraft.fluid.Fluid) BlockPos(net.minecraft.util.math.BlockPos) Map(java.util.Map)

Example 15 with IEnergyContainer

use of mekanism.api.energy.IEnergyContainer in project Mekanism by mekanism.

the class ModuleFarmingUnit method tillAOE.

private ActionResultType tillAOE(ItemUseContext context, ToolType toolType, SoundEvent sound, FloatingLong energyUsage) {
    PlayerEntity player = context.getPlayer();
    if (player == null || player.isShiftKeyDown()) {
        // Skip if we don't have a player, or they are sneaking
        return ActionResultType.PASS;
    }
    Direction sideHit = context.getClickedFace();
    if (sideHit == Direction.DOWN) {
        // Don't allow tilling a block from underneath
        return ActionResultType.PASS;
    }
    int diameter = farmingRadius.get().getRadius();
    if (diameter == 0) {
        // If we don't have any blocks we are going to want to do, then skip it
        return ActionResultType.PASS;
    }
    ItemStack stack = context.getItemInHand();
    IEnergyContainer energyContainer = StorageUtils.getEnergyContainer(stack, 0);
    if (energyContainer == null) {
        return ActionResultType.FAIL;
    }
    FloatingLong energy = energyContainer.getEnergy();
    if (energy.smallerThan(energyUsage)) {
        // Fail if we don't have enough energy or using the item failed
        return ActionResultType.FAIL;
    }
    World world = context.getLevel();
    BlockPos pos = context.getClickedPos();
    BlockState tilledState = world.getBlockState(pos).getToolModifiedState(world, pos, player, stack, toolType);
    if (tilledState == null) {
        // Skip tilling the blocks if the one we clicked cannot be tilled
        return ActionResultType.PASS;
    }
    BlockPos abovePos = pos.above();
    BlockState aboveState = world.getBlockState(abovePos);
    // Check to make sure the block above is not opaque
    if (aboveState.isSolidRender(world, abovePos)) {
        // If the block above our source is opaque, just skip tiling in general
        return ActionResultType.PASS;
    }
    if (world.isClientSide) {
        return ActionResultType.SUCCESS;
    }
    // Processing did not happen, so we need to process it
    world.setBlock(pos, tilledState, BlockFlags.DEFAULT_AND_RERENDER);
    Material aboveMaterial = aboveState.getMaterial();
    if (aboveMaterial == Material.PLANT || aboveMaterial == Material.REPLACEABLE_PLANT) {
        world.destroyBlock(abovePos, true);
    }
    world.playSound(null, pos, sound, SoundCategory.BLOCKS, 1.0F, 1.0F);
    FloatingLong energyUsed = energyUsage.copy();
    int radius = (diameter - 1) / 2;
    for (BlockPos newPos : BlockPos.betweenClosed(pos.offset(-radius, 0, -radius), pos.offset(radius, 0, radius))) {
        if (pos.equals(newPos)) {
            // Skip the source position as it is free, and we manually handled it before the loop
            continue;
        } else if (energyUsed.add(energyUsage).greaterThan(energy)) {
            break;
        }
        BlockState stateAbove = world.getBlockState(newPos.above());
        // the same as the one we got on the initial block we interacted with
        if (!stateAbove.isSolidRender(world, newPos.above()) && tilledState == world.getBlockState(newPos).getToolModifiedState(world, newPos, player, stack, toolType)) {
            // Some of the below methods don't behave properly when the BlockPos is mutable, so now that we are onto ones where it may actually
            // matter we make sure to get an immutable instance of newPos
            newPos = newPos.immutable();
            // Add energy cost
            energyUsed = energyUsed.plusEqual(energyUsage);
            // Replace the block. Note it just directly sets it (in the same way that HoeItem/ShovelItem do)
            world.setBlock(newPos, tilledState, BlockFlags.DEFAULT_AND_RERENDER);
            aboveMaterial = stateAbove.getMaterial();
            if (aboveMaterial == Material.PLANT || aboveMaterial == Material.REPLACEABLE_PLANT) {
                // If the block above the one we tilled is a plant, then we try to remove it
                world.destroyBlock(newPos.above(), true);
            }
            world.playSound(null, newPos, sound, SoundCategory.BLOCKS, 1.0F, 1.0F);
            Mekanism.packetHandler.sendToAllTracking(new PacketLightningRender(LightningPreset.TOOL_AOE, Objects.hash(pos, newPos), Vector3d.upFromBottomCenterOf(pos, 0.94), Vector3d.upFromBottomCenterOf(newPos, 0.94), 10), world, pos);
        }
    }
    energyContainer.extract(energyUsed, Action.EXECUTE, AutomationType.MANUAL);
    return ActionResultType.SUCCESS;
}
Also used : FloatingLong(mekanism.api.math.FloatingLong) IEnergyContainer(mekanism.api.energy.IEnergyContainer) BlockState(net.minecraft.block.BlockState) PacketLightningRender(mekanism.common.network.to_client.PacketLightningRender) BlockPos(net.minecraft.util.math.BlockPos) Material(net.minecraft.block.material.Material) ItemStack(net.minecraft.item.ItemStack) World(net.minecraft.world.World) Direction(net.minecraft.util.Direction) PlayerEntity(net.minecraft.entity.player.PlayerEntity)

Aggregations

IEnergyContainer (mekanism.api.energy.IEnergyContainer)34 FloatingLong (mekanism.api.math.FloatingLong)26 BlockPos (net.minecraft.util.math.BlockPos)13 PlayerEntity (net.minecraft.entity.player.PlayerEntity)12 ItemStack (net.minecraft.item.ItemStack)12 Nonnull (javax.annotation.Nonnull)10 Direction (net.minecraft.util.Direction)8 World (net.minecraft.world.World)8 BlockState (net.minecraft.block.BlockState)6 ServerPlayerEntity (net.minecraft.entity.player.ServerPlayerEntity)6 ArrayList (java.util.ArrayList)5 List (java.util.List)4 Map (java.util.Map)4 Nullable (javax.annotation.Nullable)4 TileEntityMekanism (mekanism.common.tile.base.TileEntityMekanism)4 TileEntity (net.minecraft.tileentity.TileEntity)4 SyncableFloatingLong (mekanism.common.inventory.container.sync.SyncableFloatingLong)3 EnumMap (java.util.EnumMap)2 HashMap (java.util.HashMap)2 Set (java.util.Set)2