use of mekanism.common.util.MekanismUtils.FluidInDetails 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);
}
}
}
use of mekanism.common.util.MekanismUtils.FluidInDetails in project Mekanism by mekanism.
the class ModuleElectrolyticBreathingUnit method tickServer.
@Override
public void tickServer(IModule<ModuleElectrolyticBreathingUnit> module, PlayerEntity player) {
int productionRate = 0;
// Check if the mask is underwater
// Note: Being in water is checked first to ensure that if it is raining and the player is in water
// they get the full strength production
float eyeHeight = player.getEyeHeight();
Map<Fluid, FluidInDetails> fluidsIn = MekanismUtils.getFluidsIn(player, bb -> {
// Grab the center of the BB as that is where the player is for purposes of what it renders it intersects with
double centerX = (bb.minX + bb.maxX) / 2;
double centerZ = (bb.minZ + bb.maxZ) / 2;
// For the y range check a range of where the mask's breathing unit is based on where the eyes are
return new AxisAlignedBB(centerX, Math.min(bb.minY + eyeHeight - 0.27, bb.maxY), centerZ, centerX, Math.min(bb.minY + eyeHeight - 0.14, bb.maxY), centerZ);
});
if (fluidsIn.entrySet().stream().anyMatch(entry -> entry.getKey().is(FluidTags.WATER) && entry.getValue().getMaxHeight() >= 0.11)) {
// If the position the bottom of the mask is almost entirely in water set the production rate to our max rate
// if the mask is only partially in water treat it as not being in it enough to actually function
productionRate = getMaxRate(module);
} else if (player.isInRain()) {
// If the player is not in water but is in rain set the production to half power
productionRate = getMaxRate(module) / 2;
}
if (productionRate > 0) {
FloatingLong usage = MekanismConfig.general.FROM_H2.get().multiply(2);
int maxRate = Math.min(productionRate, module.getContainerEnergy().divideToInt(usage));
long hydrogenUsed = 0;
GasStack hydrogenStack = MekanismGases.HYDROGEN.getStack(maxRate * 2L);
ItemStack chestStack = player.getItemBySlot(EquipmentSlotType.CHEST);
if (checkChestPlate(chestStack)) {
Optional<IGasHandler> chestCapability = chestStack.getCapability(Capabilities.GAS_HANDLER_CAPABILITY).resolve();
if (chestCapability.isPresent()) {
hydrogenUsed = maxRate * 2L - chestCapability.get().insertChemical(hydrogenStack, Action.EXECUTE).getAmount();
hydrogenStack.shrink(hydrogenUsed);
}
}
if (fillHeld.get()) {
ItemStack handStack = player.getItemBySlot(EquipmentSlotType.MAINHAND);
Optional<IGasHandler> handCapability = handStack.getCapability(Capabilities.GAS_HANDLER_CAPABILITY).resolve();
if (handCapability.isPresent()) {
hydrogenUsed = maxRate * 2L - handCapability.get().insertChemical(hydrogenStack, Action.EXECUTE).getAmount();
}
}
int oxygenUsed = Math.min(maxRate, player.getMaxAirSupply() - player.getAirSupply());
long used = Math.max((int) Math.ceil(hydrogenUsed / 2D), oxygenUsed);
module.useEnergy(player, usage.multiply(used));
player.setAirSupply(player.getAirSupply() + oxygenUsed);
}
}
Aggregations