Add sounds for some electric components

Add multimeter tooltip translation
Refactor Air intake a bit
This commit is contained in:
Daniel
2025-07-20 02:42:16 +03:00
parent 27dbd59568
commit abfa7cd825
16 changed files with 409 additions and 399 deletions

View File

@@ -606,6 +606,9 @@
"create.multimeter.energy_usage": " :ǝbɐs∩ ʎbɹǝuƎ ",
"create.multimeter.group": " :dnoɹ⅁ ",
"create.multimeter.header": ":ɐʇɐᗡ ɹǝʇǝɯıʇןnW",
"create.multimeter.network_power_consumption": " :uoıʇdɯnsuoɔ ɹǝʍod ʞɹoʍʇǝN",
"create.multimeter.network_power_generation": " :uoıʇɐɹǝuǝb ɹǝʍod ʞɹoʍʇǝN",
"create.multimeter.not_enough_power": "¡ᴚƎMOԀ H⅁∩ONƎ ⟘ON",
"create.multimeter.power_generated": " :pǝʇɐɹǝuǝ⅁ ɹǝʍoԀ ",
"create.multimeter.power_percentage": " :ɥʇbuǝɹʇS pıɹ⅁ ",
"create.multimeter.power_usage": " :ǝbɐs∩ ɹǝʍoԀ ",
@@ -1078,6 +1081,10 @@
"tfmg.ponder.tag.metallurgy.description": "ןɐʇǝɯ buıssǝɔoɹd oʇ pǝʇɐןǝɹ sʞɔoןᗺ",
"tfmg.ponder.tag.oil_processing": "ʎɹǝuıɥɔɐW buıssǝɔoɹԀ ןıO",
"tfmg.ponder.tag.oil_processing.description": "ןıo buıuıɯ puɐ buıuıɟǝɹ ɹoɟ pǝsn ʞɔoןᗺ",
"tfmg.subtitle.diesel_engine_sounds": "spunoS ǝuıbuƎ ןǝsǝıᗡ",
"tfmg.subtitle.engine_sounds": "spunoS ǝuıbuƎ"
"tfmg.subtitle.diesel_engine_sounds": "spunos ǝuıbuƎ ןǝsǝıᗡ",
"tfmg.subtitle.electric_hum": "ɯnɥ ɔıɹʇɔǝןƎ",
"tfmg.subtitle.engine_sounds": "spunos ǝuıbuƎ",
"tfmg.subtitle.generator_hum": "ɯnɥ ɹoʇɐɹǝuǝ⅁",
"tfmg.subtitle.switch_off": "buıuǝdo ɥɔʇıʍS",
"tfmg.subtitle.switch_on": "buısoןɔ ɥɔʇıʍS"
}

View File

@@ -606,6 +606,9 @@
"create.multimeter.energy_usage": " Energy Usage: ",
"create.multimeter.group": " Group: ",
"create.multimeter.header": "Multimeter Data:",
"create.multimeter.network_power_consumption": "Network power consumption: ",
"create.multimeter.network_power_generation": "Network power generation: ",
"create.multimeter.not_enough_power": "NOT ENOUGH POWER!",
"create.multimeter.power_generated": " Power Generated: ",
"create.multimeter.power_percentage": " Grid Strength: ",
"create.multimeter.power_usage": " Power Usage: ",
@@ -1078,6 +1081,10 @@
"tfmg.ponder.tag.metallurgy.description": "Blocks related to processing metal",
"tfmg.ponder.tag.oil_processing": "Oil Processing Machinery",
"tfmg.ponder.tag.oil_processing.description": "Block used for refining and mining oil",
"tfmg.subtitle.diesel_engine_sounds": "Diesel Engine Sounds",
"tfmg.subtitle.engine_sounds": "Engine Sounds"
"tfmg.subtitle.diesel_engine_sounds": "Diesel Engine sounds",
"tfmg.subtitle.electric_hum": "Electric hum",
"tfmg.subtitle.engine_sounds": "Engine sounds",
"tfmg.subtitle.generator_hum": "Generator hum",
"tfmg.subtitle.switch_off": "Switch opening",
"tfmg.subtitle.switch_on": "Switch closing"
}

View File

@@ -133,7 +133,7 @@ public interface IElectric {
.forGoggles(tooltip);
if (getData().notEnoughtPower) {
CreateLang.text("NOT ENOUGHT POWER")
CreateLang.translate("multimeter.not_enough_power")
.color(Color.RED)
.forGoggles(tooltip, 1);
@@ -186,11 +186,13 @@ public interface IElectric {
CreateLang.text("----------------------------")
.style(ChatFormatting.WHITE)
.forGoggles(tooltip);
CreateLang.text("Network Power Generation: " + TFMGUtils.formatUnits(getNetworkPowerGeneration(), "W"))
CreateLang.translate("multimeter.network_power_generation")
.add(Component.literal(TFMGUtils.formatUnits(getNetworkPowerGeneration(), "W")))
.color(0xcc4b74)
.forGoggles(tooltip, 1);
CreateLang.text("Network Power Consumption: " + TFMGUtils.formatUnits(getNetworkPowerUsage(), "W"))
CreateLang.translate("multimeter.network_power_consumption")
.add(Component.literal(TFMGUtils.formatUnits(getNetworkPowerUsage(), "W")))
.color(0xcc4b74)
.forGoggles(tooltip, 1);
@@ -325,4 +327,4 @@ public interface IElectric {
}
}
}

View File

@@ -3,6 +3,7 @@ package com.drmangotea.tfmg.content.electricity.generators;
import com.drmangotea.tfmg.TFMG;
import com.drmangotea.tfmg.config.TFMGConfigs;
import com.drmangotea.tfmg.content.electricity.base.KineticElectricBlockEntity;
import com.drmangotea.tfmg.registry.TFMGSoundEvents;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
@@ -32,6 +33,26 @@ public class GeneratorBlockEntity extends KineticElectricBlockEntity {
updateNetwork();
data.updateNextTick = false;
}
if (level.isClientSide()) {
float speed = Math.abs(getSpeed());
float minSpeed = TFMGConfigs.common().machines.largeGeneratorMinSpeed.getF();
// Only play sound if above minimum speed
if (speed > minSpeed) {
float maxSpeed = 255f; // Max expected speed
// Normalize speed between 0-1 range (clamped)
float normalizedSpeed = Math.min(1.0f, (speed - minSpeed) / (maxSpeed - minSpeed));
// Volume scales from 0.1 to 0.5 with speed
float volume = 0.1f + (0.4f * normalizedSpeed);
// Pitch scales from 0.8 to 1.2 with speed (Java clamps below 0.5)
float pitch = 0.8f + (0.4f * normalizedSpeed);
TFMGSoundEvents.GENERATOR_HUM.playAt(level, worldPosition, volume, pitch, false);
}
}
}
@Override

View File

@@ -5,6 +5,7 @@ import com.drmangotea.tfmg.config.TFMGConfigs;
import com.drmangotea.tfmg.content.electricity.base.KineticElectricBlockEntity;
import com.drmangotea.tfmg.content.electricity.generators.large_generator.StatorBlock.StatorState;
import com.drmangotea.tfmg.registry.TFMGBlocks;
import com.drmangotea.tfmg.registry.TFMGSoundEvents;
import net.createmod.catnip.animation.LerpedFloat;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
@@ -57,6 +58,26 @@ public class RotorBlockEntity extends KineticElectricBlockEntity {
findStators();
findNextTick = false;
}
if (level.isClientSide()) {
float speed = Math.abs(visualSpeed.getValue());
float minSpeed = TFMGConfigs.common().machines.largeGeneratorMinSpeed.getF();
// Only play sound if above minimum speed
if (speed > minSpeed) {
float maxSpeed = 255f; // Max expected speed
// Normalize speed between 0-1 range (clamped)
float normalizedSpeed = Math.min(1.0f, (speed - minSpeed) / (maxSpeed - minSpeed));
// Volume scales from 0.1 to 1.0 with speed
float volume = 0.1f + (0.9f * normalizedSpeed);
// Pitch scales from 0.5 to 1.0 with speed (Java clamps below 0.5)
float pitch = 0.5f + (0.5f * normalizedSpeed);
TFMGSoundEvents.GENERATOR_HUM.playAt(level, worldPosition, volume, pitch, false);
}
}
}
@Override
@@ -84,9 +105,9 @@ public class RotorBlockEntity extends KineticElectricBlockEntity {
return 0;
float modifier = TFMGConfigs.common().machines.largeGeneratorModifier.getF();
float maxSpeed = TFMGConfigs.common().machines.largeGeneratorMinSpeed.getF();
float minSpeed = TFMGConfigs.common().machines.largeGeneratorMinSpeed.getF();
return (int) Math.max(0, ((Math.abs(getSpeed()) - maxSpeed) * modifier));
return (int) Math.max(0, ((Math.abs(getSpeed()) - minSpeed) * modifier));
}
@Override
@@ -202,4 +223,4 @@ public class RotorBlockEntity extends KineticElectricBlockEntity {
}
}
}

View File

@@ -1,7 +1,8 @@
package com.drmangotea.tfmg.content.electricity.utilities.electric_switch;
import com.drmangotea.tfmg.content.electricity.base.IElectric;
import com.drmangotea.tfmg.content.electricity.utilities.diode.ElectricDiodeBlockEntity;
import com.drmangotea.tfmg.registry.TFMGSoundEvents;
import com.simibubi.create.Create;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.entity.BlockEntityType;
@@ -42,6 +43,14 @@ public class ElectricSwitchBlockEntity extends ElectricDiodeBlockEntity {
updateInFrontNextTick();
updateNextTick();
if (level.isClientSide()) {
if (signal == 0)
TFMGSoundEvents.SWITCH_OFF.playAt(level, worldPosition, 0.8f + Create.RANDOM.nextFloat() * 0.4f, 0.8f + Create.RANDOM.nextFloat() * 0.4f, false);
else
TFMGSoundEvents.SWITCH_ON.playAt(level, worldPosition, 0.8f + Create.RANDOM.nextFloat() * 0.4f, 0.8f + Create.RANDOM.nextFloat() * 0.4f, false);
}
}
public void neighbourChanged() {

View File

@@ -2,11 +2,13 @@ package com.drmangotea.tfmg.content.electricity.utilities.transformer;
import com.drmangotea.tfmg.TFMG;
import com.drmangotea.tfmg.base.blocks.TFMGHorizontalDirectionalBlock;
import com.drmangotea.tfmg.config.TFMGConfigs;
import com.drmangotea.tfmg.content.electricity.base.IElectric;
import com.drmangotea.tfmg.content.electricity.base.UpdateInFrontPacket;
import com.drmangotea.tfmg.content.electricity.base.VoltageAlteringBlockEntity;
import com.drmangotea.tfmg.registry.TFMGPackets;
import com.drmangotea.tfmg.registry.TFMGSoundEvents;
import com.simibubi.create.foundation.utility.CreateLang;
import net.minecraft.ChatFormatting;
import net.minecraft.core.BlockPos;
@@ -63,6 +65,9 @@ public class TransformerBlockEntity extends VoltageAlteringBlockEntity {
updateInFront();
updateInFront = false;
}
if (this.getPowerUsage() > 0 && this.level.isClientSide())
TFMGSoundEvents.ELECTRIC_HUM.playAt(level, worldPosition, 1.0f, 1.0f, false);
}
@Override

View File

@@ -4,8 +4,6 @@ import com.drmangotea.tfmg.registry.TFMGFluids;
import com.simibubi.create.content.equipment.wrench.IWrenchable;
import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
import com.simibubi.create.foundation.fluid.SmartFluidTank;
import com.simibubi.create.foundation.utility.CreateLang;
import net.createmod.catnip.animation.LerpedFloat;
import net.createmod.catnip.lang.LangBuilder;
@@ -35,441 +33,336 @@ import static com.drmangotea.tfmg.content.machinery.misc.air_intake.AirIntakeBlo
import static com.simibubi.create.content.kinetics.base.DirectionalKineticBlock.FACING;
public class AirIntakeBlockEntity extends KineticBlockEntity implements IWrenchable {
private static final int SMALL_FAN_DIAMETER = 1;
private static final int MEDIUM_FAN_DIAMETER = 2;
private static final int LARGE_FAN_DIAMETER = 3;
int diameter = 1;
boolean isController=false;
public boolean hasShaft=true;
int diameter = SMALL_FAN_DIAMETER;
boolean isController = false;
public boolean hasShaft = true;
boolean isUsedByController = false;
public BlockPos controller;
public List<AirIntakeBlockEntity> blockEntities = new ArrayList<>();
public float maxShaftSpeed =0;
public float maxShaftSpeed = 0;
public float angle = 0;
public LerpedFloat visual_angle = LerpedFloat.angular();
protected FluidTank tankInventory;
protected LazyOptional<IFluidHandler> fluidCapability;
public AirIntakeBlockEntity(BlockEntityType<?> typeIn, BlockPos pos, BlockState state) {
super(typeIn, pos, state);
tankInventory = createInventory();
fluidCapability = LazyOptional.of(() -> tankInventory);
}
public void tick(){
public void tick() {
super.tick();
//if(!level.isClientSide) {
int production = ((int) maxShaftSpeed * ((diameter * diameter))) / 40;
if (tankInventory.getFluidAmount() + production <= tankInventory.getCapacity()) {
//tankInventory.fill(new FluidStack(TFMGFluids.AIR.getSource(), production), IFluidHandler.FluidAction.EXECUTE);
tankInventory.setFluid(new FluidStack(TFMGFluids.AIR.getSource(), production + tankInventory.getFluidAmount()));
// if(controller!=null) {
// ((AirIntakeBlockEntity) level.getBlockEntity(controller)).setChanged();
// ((AirIntakeBlockEntity) level.getBlockEntity(controller)).sendData();
// }
}
// }
////////////////
produceAir();
updateVisuals();
updateBlockState();
validateController();
updateShaftSpeed();
validateMultiblock();
}
if(isUsedByController) {
private void produceAir() {
int production = ((int) maxShaftSpeed * (diameter * diameter)) / 40;
if (tankInventory.getFluidAmount() + production <= tankInventory.getCapacity()) {
tankInventory.setFluid(new FluidStack(TFMGFluids.AIR.getSource(), production + tankInventory.getFluidAmount()));
}
if (isUsedByController) {
refreshCapability();
sendData();
setChanged();
}
}
if(diameter == 3){
private void updateVisuals() {
if (diameter == LARGE_FAN_DIAMETER) {
visual_angle.chase(angle, 0.1f, LerpedFloat.Chaser.EXP);
visual_angle.tickChaser();
}
angle+=maxShaftSpeed/2;
angle += maxShaftSpeed / 2;
angle %= 360;
}
if(isUsedByController)
blockEntities.clear();
if(!this.getBlockState().getValue(INVISIBLE)){
if(isController||isUsedByController){
level.setBlock(this.getBlockPos(),this.getBlockState().setValue(INVISIBLE,true),2);
private void updateBlockState() {
if (!this.getBlockState().getValue(INVISIBLE)) {
if (isController || isUsedByController) {
level.setBlock(this.getBlockPos(), this.getBlockState().setValue(INVISIBLE, true), 2);
}
}
if(!isController&&!isUsedByController)
level.setBlock(this.getBlockPos(),this.getBlockState().setValue(INVISIBLE,false),2);
if (!isController && !isUsedByController) {
level.setBlock(this.getBlockPos(), this.getBlockState().setValue(INVISIBLE, false), 2);
}
}
if(controller == null)
controller = this.getBlockPos();
diameter =getPossibleDiameter();
if(controller == this.getBlockPos()) {
private void validateController() {
if (controller == null) controller = this.getBlockPos();
diameter = getPossibleDiameter();
if (controller == this.getBlockPos()) {
isUsedByController = false;
} else {
isUsedByController = true;
isController = false;
}
if(diameter ==1) {
if (diameter == SMALL_FAN_DIAMETER) {
isController = false;
}
if(!(level.getBlockEntity(controller) instanceof AirIntakeBlockEntity)) {
if (!(level.getBlockEntity(controller) instanceof AirIntakeBlockEntity)) {
isUsedByController = false;
controller = this.getBlockPos();
} else {
if(!(((AirIntakeBlockEntity) level.getBlockEntity(controller)).isController))
isUsedByController = false;
} else if (!(((AirIntakeBlockEntity) level.getBlockEntity(controller)).isController)) {
isUsedByController = false;
}
//else
// if(!(((AirIntakeBlockEntity) level.getBlockEntity(controller)).isController))
// controller = this.getBlockPos();
if(controller!=null) {
if(level.getBlockEntity(controller)!=null)
if(((AirIntakeBlockEntity)level.getBlockEntity(controller)).diameter==2) {
int x = Math.abs(this.getBlockPos().getX() - controller.getX());
int y = Math.abs(this.getBlockPos().getY() - controller.getY());
int z = Math.abs(this.getBlockPos().getZ() - controller.getZ());
validateControllerDistance();
}
int distanceFromController = x + y + z;
if (x > 1 || y > 1 || z > 1) {
isUsedByController = false;
controller = this.getBlockPos();
}
}
if(level.getBlockEntity(controller)!=null)
if(((AirIntakeBlockEntity)level.getBlockEntity(controller)).diameter==1) {
private void validateControllerDistance() {
if (controller == null || level.getBlockEntity(controller) == null) return;
AirIntakeBlockEntity controllerBE = (AirIntakeBlockEntity) level.getBlockEntity(controller);
if (controllerBE.diameter == MEDIUM_FAN_DIAMETER) {
int x = Math.abs(this.getBlockPos().getX() - controller.getX());
int y = Math.abs(this.getBlockPos().getY() - controller.getY());
int z = Math.abs(this.getBlockPos().getZ() - controller.getZ());
if (x > 1 || y > 1 || z > 1) {
isUsedByController = false;
controller = this.getBlockPos();
}
} else if (controllerBE.diameter == SMALL_FAN_DIAMETER) {
isUsedByController = false;
controller = this.getBlockPos();
}
////////////////////////
if(diameter == 1){
maxShaftSpeed = Math.abs(getSpeed());
}else {
maxShaftSpeed = Math.abs(getSpeed());
List<Float> speeds = new ArrayList<>();
//
for (AirIntakeBlockEntity be : blockEntities) {
speeds.add(Math.abs(be.getSpeed()));
//
}
//
for(float testedSpeed : speeds){
if(testedSpeed> maxShaftSpeed)
maxShaftSpeed = testedSpeed;
}
// maxShaftSpeed = getSpeed();
}
if(isUsedByController)
return;
if(diameter ==2){
if(blockEntities.toArray().length!=4)
return;
}
if(diameter ==3){
if(blockEntities.toArray().length!=9)
return;
}
}
private void updateShaftSpeed() {
maxShaftSpeed = Math.abs(getSpeed());
if (diameter > SMALL_FAN_DIAMETER) {
for (AirIntakeBlockEntity be : blockEntities) {
float testedSpeed = Math.abs(be.getSpeed());
if (testedSpeed > maxShaftSpeed) {
maxShaftSpeed = testedSpeed;
}
}
}
}
private void validateMultiblock() {
if (isUsedByController) return;
if ((diameter == MEDIUM_FAN_DIAMETER && blockEntities.size() != MEDIUM_FAN_DIAMETER * MEDIUM_FAN_DIAMETER)
|| (diameter == LARGE_FAN_DIAMETER && blockEntities.size() != LARGE_FAN_DIAMETER * LARGE_FAN_DIAMETER)) return;
}
@Override
public void invalidate() {
super.invalidate();
fluidCapability.invalidate();
}
public InteractionResult onWrenched(BlockState state, UseOnContext context){
public InteractionResult onWrenched(BlockState state, UseOnContext context) {
Direction direction = context.getClickedFace();
if(direction == getBlockState().getValue(FACING).getOpposite()) {
if (direction == getBlockState().getValue(FACING).getOpposite()) {
hasShaft = !hasShaft;
}
return InteractionResult.SUCCESS;
}
public void setController(BlockPos controllerPos) {
// isUsedByController = true;
controller = controllerPos;
controller = controllerPos;
}
@Nonnull
@Override
@SuppressWarnings("removal")
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, Direction side) {
if (!fluidCapability.isPresent()) {
refreshCapability();
sendData();
setChanged();
}
if (cap == ForgeCapabilities.FLUID_HANDLER)
return fluidCapability.cast();
if (cap == ForgeCapabilities.FLUID_HANDLER) return fluidCapability.cast();
return super.getCapability(cap, side);
}
private void refreshCapability() {
IFluidHandler handlerForCapability;
if (controller == null || controller == this.getBlockPos()
) {
if (controller == null || controller == this.getBlockPos()) {
handlerForCapability = tankInventory;
} else
if(((AirIntakeBlockEntity) level.getBlockEntity(controller))!=null) {
} else if (level.getBlockEntity(controller) != null) {
handlerForCapability = ((AirIntakeBlockEntity) level.getBlockEntity(controller)).tankInventory;
}else handlerForCapability = tankInventory;
} else {
handlerForCapability = tankInventory;
}
LazyOptional<IFluidHandler> oldCap = fluidCapability;
IFluidHandler finalHandlerForCapability = handlerForCapability;
fluidCapability = LazyOptional.of(() -> finalHandlerForCapability);
//oldCap.invalidate();
}
public int getPossibleDiameter() {
if (controller != this.getBlockPos()) return SMALL_FAN_DIAMETER;
boolean canBeMedium = checkMediumDiameter();
boolean canBeLarge = checkLargeDiameter();
public int getPossibleDiameter(){
if(controller !=this.getBlockPos())
return 1;
BlockPos checkedPos = this.getBlockPos();
Direction direction = this.getBlockState().getValue(FACING);
List<BlockPos> checkedPosses = new ArrayList<>();
checkedPos = this.getBlockPos();
boolean canBeMedium = true;
for(int x = 0;x < 2; x++){
for(int z = 0;z < 2; z++){
checkedPosses.add(checkedPos);
if(direction.getAxis().isHorizontal()) {
checkedPos = checkedPos.above();
}else checkedPos = checkedPos.east();
}
if(direction.getAxis().isHorizontal()) {
checkedPos = checkedPos.below(2);
checkedPos = checkedPos.relative(direction.getClockWise());
} else {
checkedPos = checkedPos.west(2);
checkedPos = checkedPos.south();
}
if (canBeLarge) {
setupMultiblock(LARGE_FAN_DIAMETER);
return LARGE_FAN_DIAMETER;
}
List<BlockPos> checkedPossesLarge = new ArrayList<>();
checkedPos = this.getBlockPos();
boolean canBeLarge = true;
for(int x = 0;x < 3; x++){
for(int z = 0;z < 3; z++){
checkedPossesLarge.add(checkedPos);
if(direction.getAxis().isHorizontal()) {
checkedPos = checkedPos.above();
}else checkedPos = checkedPos.east();
}
if(direction.getAxis().isHorizontal()) {
checkedPos = checkedPos.below(3);
checkedPos = checkedPos.relative(direction.getClockWise());
} else {
checkedPos = checkedPos.west(3);
checkedPos = checkedPos.south();
}
}
//LARGE
for(BlockPos pos : checkedPossesLarge){
if(!(level.getBlockEntity(pos) instanceof AirIntakeBlockEntity)) {
canBeLarge = false;
break;
}
// ((AirIntakeBlockEntity) level.getBlockEntity(pos)).controller = this.getBlockPos();
AirIntakeBlockEntity checkedBE = (AirIntakeBlockEntity) level.getBlockEntity(pos);
//if(checkedBE.diameter<3)
// ((AirIntakeBlockEntity) level.getBlockEntity(pos)).isController = false;
// if(pos!=this.getBlockPos())
// if(checkedBE.isController) {
//
//
// canBeLarge = false;
// break;
// }
if(checkedBE.getBlockState().getValue(FACING) != this.getBlockState().getValue(FACING)) {
canBeLarge = false;
break;
}
//if(pos!=this.getBlockPos())
// ((AirIntakeBlockEntity) level.getBlockEntity(pos)).isUsedByController = true;
}
//MEDIUM
for(BlockPos pos : checkedPosses){
if(!(level.getBlockEntity(pos) instanceof AirIntakeBlockEntity)) {
canBeMedium = false;
break;
}
// ((AirIntakeBlockEntity) level.getBlockEntity(pos)).controller = this.getBlockPos();
AirIntakeBlockEntity checkedBE = (AirIntakeBlockEntity) level.getBlockEntity(pos);
if(pos!=this.getBlockPos())
if(checkedBE.isController) {
canBeMedium = false;
break;
}
if(checkedBE.getBlockState().getValue(FACING) != this.getBlockState().getValue(FACING)) {
canBeMedium = false;
break;
}
//if(pos!=this.getBlockPos())
// ((AirIntakeBlockEntity) level.getBlockEntity(pos)).isUsedByController = true;
}
if(canBeLarge) {
this.blockEntities.clear();
for(BlockPos pos : checkedPossesLarge) {
//if(((AirIntakeBlockEntity) level.getBlockEntity(pos)).isUsedByController&&((AirIntakeBlockEntity) level.getBlockEntity(pos)).controller!=this.getBlockPos()&&pos!=this.getBlockPos()) {
// controller = this.getBlockPos();
// isController = false;
// return 1;
//}
if((((AirIntakeBlockEntity) level.getBlockEntity(pos)).isUsedByController&&((AirIntakeBlockEntity) level.getBlockEntity(pos)).controller!=this.getBlockPos()&&pos!=this.getBlockPos())||isController) {
((AirIntakeBlockEntity) level.getBlockEntity(pos)).isUsedByController = true;
((AirIntakeBlockEntity) level.getBlockEntity(pos)).isController = false;
((AirIntakeBlockEntity) level.getBlockEntity(pos)).controller =this.getBlockPos();
}
((AirIntakeBlockEntity) level.getBlockEntity(pos)).setController(this.getBlockPos());
this.blockEntities.add((AirIntakeBlockEntity) level.getBlockEntity(pos));
}
controller = this.getBlockPos();
isController = true;
return 3;
}
if(canBeMedium) {
this.blockEntities.clear();
for(BlockPos pos : checkedPosses) {
if(((AirIntakeBlockEntity) level.getBlockEntity(pos)).isUsedByController&&((AirIntakeBlockEntity) level.getBlockEntity(pos)).controller!=this.getBlockPos()&&pos!=this.getBlockPos()) {
controller = this.getBlockPos();
isController = false;
return 1;
}
((AirIntakeBlockEntity) level.getBlockEntity(pos)).setController(this.getBlockPos());
this.blockEntities.add((AirIntakeBlockEntity) level.getBlockEntity(pos));
}
controller = this.getBlockPos();
isController = true;
return 2;
if (canBeMedium) {
setupMultiblock(MEDIUM_FAN_DIAMETER);
return MEDIUM_FAN_DIAMETER;
}
controller = this.getBlockPos();
isController = false;
return 1;
return SMALL_FAN_DIAMETER;
}
private boolean checkMediumDiameter() {
List<BlockPos> checkedPosses = new ArrayList<>();
BlockPos checkedPos = this.getBlockPos();
Direction direction = this.getBlockState().getValue(FACING);
for (int x = 0; x < MEDIUM_FAN_DIAMETER; x++) {
for (int z = 0; z < MEDIUM_FAN_DIAMETER; z++) {
checkedPosses.add(checkedPos);
if (direction.getAxis().isHorizontal()) {
checkedPos = checkedPos.above();
} else {
checkedPos = checkedPos.east();
}
}
if (direction.getAxis().isHorizontal()) {
checkedPos = checkedPos.below(MEDIUM_FAN_DIAMETER);
checkedPos = checkedPos.relative(direction.getClockWise());
} else {
checkedPos = checkedPos.west(MEDIUM_FAN_DIAMETER);
checkedPos = checkedPos.south();
}
}
for (BlockPos pos : checkedPosses) {
if (!(level.getBlockEntity(pos) instanceof AirIntakeBlockEntity)) return false;
AirIntakeBlockEntity checkedBE = (AirIntakeBlockEntity) level.getBlockEntity(pos);
if (pos != this.getBlockPos() && checkedBE.isController) return false;
if (checkedBE.getBlockState().getValue(FACING) != this.getBlockState().getValue(FACING)) return false;
}
return true;
}
private boolean checkLargeDiameter() {
List<BlockPos> checkedPosses = new ArrayList<>();
BlockPos checkedPos = this.getBlockPos();
Direction direction = this.getBlockState().getValue(FACING);
for (int x = 0; x < LARGE_FAN_DIAMETER; x++) {
for (int z = 0; z < LARGE_FAN_DIAMETER; z++) {
checkedPosses.add(checkedPos);
if (direction.getAxis().isHorizontal()) {
checkedPos = checkedPos.above();
} else {
checkedPos = checkedPos.east();
}
}
if (direction.getAxis().isHorizontal()) {
checkedPos = checkedPos.below(LARGE_FAN_DIAMETER);
checkedPos = checkedPos.relative(direction.getClockWise());
} else {
checkedPos = checkedPos.west(LARGE_FAN_DIAMETER);
checkedPos = checkedPos.south();
}
}
for (BlockPos pos : checkedPosses) {
if (!(level.getBlockEntity(pos) instanceof AirIntakeBlockEntity)) return false;
AirIntakeBlockEntity checkedBE = (AirIntakeBlockEntity) level.getBlockEntity(pos);
if (checkedBE.getBlockState().getValue(FACING) != this.getBlockState().getValue(FACING)) return false;
}
return true;
}
private void setupMultiblock(int diameter) {
this.blockEntities.clear();
List<BlockPos> positions = getMultiblockPositions(diameter);
for (BlockPos pos : positions) {
AirIntakeBlockEntity be = (AirIntakeBlockEntity) level.getBlockEntity(pos);
if (be.isUsedByController && be.controller != this.getBlockPos() && pos != this.getBlockPos()) {
be.isUsedByController = true;
be.isController = false;
be.controller = this.getBlockPos();
}
be.setController(this.getBlockPos());
this.blockEntities.add(be);
}
controller = this.getBlockPos();
isController = true;
}
private List<BlockPos> getMultiblockPositions(int diameter) {
List<BlockPos> positions = new ArrayList<>();
BlockPos checkedPos = this.getBlockPos();
Direction direction = this.getBlockState().getValue(FACING);
int size = diameter == MEDIUM_FAN_DIAMETER ? MEDIUM_FAN_DIAMETER : LARGE_FAN_DIAMETER;
for (int x = 0; x < size; x++) {
for (int z = 0; z < size; z++) {
positions.add(checkedPos);
if (direction.getAxis().isHorizontal()) {
checkedPos = checkedPos.above();
} else {
checkedPos = checkedPos.east();
}
}
if (direction.getAxis().isHorizontal()) {
checkedPos = checkedPos.below(size);
checkedPos = checkedPos.relative(direction.getClockWise());
} else {
checkedPos = checkedPos.west(size);
checkedPos = checkedPos.south();
}
}
return positions;
}
@Override
protected AABB createRenderBoundingBox() {
return new AABB(this.getBlockPos()).inflate(3);
}
@Override
@SuppressWarnings("removal")
public boolean addToGoggleTooltip(List<Component> tooltip, boolean isPlayerSneaking) {
//--Fluid Info--//
LazyOptional<IFluidHandler> handler = this.getCapability(ForgeCapabilities.FLUID_HANDLER);
Optional<IFluidHandler> resolve = handler.resolve();
if (!resolve.isPresent())
return false;
if (!resolve.isPresent()) return false;
IFluidHandler tank = resolve.get();
if (tank.getTanks() == 0)
return false;
if (tank.getTanks() == 0) return false;
LangBuilder mb = CreateLang.translate("generic.unit.millibuckets");
boolean isEmpty = true;
for (int i = 0; i < tank.getTanks(); i++) {
FluidStack fluidStack = tank.getFluidInTank(i);
if (fluidStack.isEmpty())
continue;
if (fluidStack.isEmpty()) continue;
CreateLang.fluidName(fluidStack)
.style(ChatFormatting.GRAY)
@@ -489,13 +382,11 @@ public class AirIntakeBlockEntity extends KineticBlockEntity implements IWrencha
}
if (tank.getTanks() > 1) {
if (isEmpty)
tooltip.remove(tooltip.size() - 1);
if (isEmpty) tooltip.remove(tooltip.size() - 1);
return true;
}
if (!isEmpty)
return true;
if (!isEmpty) return true;
CreateLang.translate("gui.goggles.fluid_container.capacity")
.add(CreateLang.number(tank.getTankCapacity(0))
@@ -503,57 +394,40 @@ public class AirIntakeBlockEntity extends KineticBlockEntity implements IWrencha
.style(ChatFormatting.DARK_GREEN))
.style(ChatFormatting.DARK_GRAY)
.forGoggles(tooltip, 1);
return true;
}
protected SmartFluidTank createInventory() {
return new SmartFluidTank(8000, this::onFluidStackChanged){
return new SmartFluidTank(8000, this::onFluidStackChanged) {
@Override
public boolean isFluidValid(FluidStack stack) {
return stack.getFluid().isSame(TFMGFluids.AIR.getSource());
}
// @Override
// public FluidStack drain(FluidStack resource, FluidAction action) {
// return FluidStack.EMPTY;
// }
};
}
protected void onFluidStackChanged(FluidStack newFluidStack) {
setChanged();
sendData();
//if(((AirIntakeBlockEntity) level.getBlockEntity(controller))!=null) {
// ((AirIntakeBlockEntity) level.getBlockEntity(controller)).setChanged();
// ((AirIntakeBlockEntity) level.getBlockEntity(controller)).sendData();
//}
setChanged();
sendData();
}
@Override
protected void read(CompoundTag compound, boolean clientPacket) {
super.read(compound, clientPacket);
diameter = compound.getInt("Diameter");
isController = compound.getBoolean("IsController");
isUsedByController = compound.getBoolean("IsUsed");
hasShaft = compound.getBoolean("HasShaft");
tankInventory.readFromNBT(compound.getCompound("TankContent"));
}
@Override
public void write(CompoundTag compound, boolean clientPacket) {
super.write(compound, clientPacket);
compound.putInt("Diameter", diameter);
compound.putBoolean("IsController", isController);
compound.putBoolean("IsUsed", isUsedByController);
compound.putBoolean("HasShaft", hasShaft);
compound.put("TankContent", tankInventory.writeToNBT(new CompoundTag()));
}
}

View File

@@ -44,18 +44,41 @@ public class TFMGSoundEvents {
public static final TFMGSoundEvents.SoundEntry
ENGINE = create("engine")
ENGINE = create("engine")
.subtitle("Engine Sounds")
.category(SoundSource.BLOCKS)
.attenuationDistance(10)
.build(),
DIESEL_ENGINE = create("diesel_engine")
.subtitle("Diesel Engine Sounds")
.category(SoundSource.BLOCKS)
.attenuationDistance(10)
.build();
DIESEL_ENGINE = create("diesel_engine")
.subtitle("Diesel Engine Sounds")
.category(SoundSource.BLOCKS)
.attenuationDistance(10)
.build(),
ELECTRIC_HUM = create("electric_hum")
.subtitle("Electric hum")
.category(SoundSource.BLOCKS)
.attenuationDistance(10)
.build(),
GENERATOR_HUM = create("generator_hum")
.subtitle("Generator hum")
.category(SoundSource.BLOCKS)
.attenuationDistance(10)
.build(),
SWITCH_ON = create("switch_on")
.subtitle("Switch closing")
.category(SoundSource.BLOCKS)
.attenuationDistance(10)
.build(),
SWITCH_OFF = create("switch_off")
.subtitle("Switch opening")
.category(SoundSource.BLOCKS)
.attenuationDistance(10)
.build();
private static SoundEntryBuilder create(String name) {
return create(TFMG.asResource(name));
@@ -433,4 +456,4 @@ public class TFMGSoundEvents {
}
}
}

View File

@@ -147,6 +147,9 @@
"tfmg.keyinfo.transmission_shift_down": "Transmission Shift Down",
"create.multimeter.header": "Multimeter Data:",
"create.multimeter.network_power_consumption": "Network power consumption: ",
"create.multimeter.network_power_generation": "Network power generation: ",
"create.multimeter.not_enough_power": "NOT ENOUGH POWER!",
"create.multimeter.additional_values": "Additional Values:",
"create.multimeter.power_usage": " Power Usage: ",
"create.multimeter.group": " Group: ",
@@ -170,8 +173,11 @@
"tfmg.subtitle.engine_sounds": "Engine Sounds",
"tfmg.subtitle.diesel_engine_sounds": "Diesel Engine Sounds"
"tfmg.subtitle.engine_sounds": "Engine sounds",
"tfmg.subtitle.diesel_engine_sounds": "Diesel Engine sounds",
"tfmg.subtitle.electric_hum": "Electric hum",
"tfmg.subtitle.generator_hum": "Generator hum",
"tfmg.subtitle.switch_on": "Switch closing",
"tfmg.subtitle.switch_off": "Switch opening"
}

View File

@@ -427,7 +427,6 @@
"block.tfmg.red_rebar_concrete_stairs": "Красные железобетонные ступеньки",
"block.tfmg.red_rebar_concrete_wall": "Красная железобетонная ограда",
"block.tfmg.regular_engine": "Стандартный двигатель",
"block.tfmg.reinforced_fireproof_bricks": "Укреплённые огнеупорные кирпичи",
"block.tfmg.resistor": "Резистор",
"block.tfmg.resistor.tooltip.behaviour1": "Добавляет сопротивление (величину можно изменить на намоточном станке) в электрическую группу подключённого блока.",
"block.tfmg.resistor.tooltip.condition1": "При установке на блок в составе группы",
@@ -607,12 +606,15 @@
"create.multimeter.energy_usage": " Потребление энергии: ",
"create.multimeter.group": " Группа: ",
"create.multimeter.header": "Данные измерений:",
"create.multimeter.power_generated": " Генерация энергии: ",
"create.multimeter.not_enough_power": "НЕДОСТАТОЧНАЯ МОЩНОСТЬ",
"create.multimeter.power_generated": " Генерируемая мощность: ",
"create.multimeter.power_percentage": " Резерв мощности сети: ",
"create.multimeter.power_usage": " Потребление мощности: ",
"create.multimeter.transformer_ratio": " Коэффициент трансформации: ",
"create.multimeter.voltage_generated": " Генерируемое напряжение: ",
"create.network": "Сеть: %1$s",
"create.multimeter.network_power_consumption": "Потребление мощности в сети: ",
"create.multimeter.network_power_generation": "Генерация мощности в сети: ",
"create.oil_hammer.reserves": "Резервы нефти: %1$s",
"create.pumpjack_deposit_amount": "%1$s вёдер",
"create.recipe.advanced_distillation": "Ректификация",
@@ -646,8 +648,8 @@
"distillation_output.mode.keep_fluid": "Останавливать процесс",
"distillation_output.mode.void_when_full": "Уничтожать избытки",
"effect.tfmg.hellfire": "Адское пламя",
"effect.tfmg.hellfire.description": "§kОписание отсутствует§r",
"entity.tfmg.blue_spark": "Синяя искра",
"entity.tfmg.dry_ice_flake": "Крошка сухого льда",
"entity.tfmg.copper_grenade": "Медная граната",
"entity.tfmg.green_spark": "Зелёная искра",
"entity.tfmg.lithium_spark": "Литиевая искра",
@@ -778,6 +780,8 @@
"item.tfmg.ethylene_bucket": "Баллон этилена",
"item.tfmg.fireclay_ball": "Комок огнеупорной глины",
"item.tfmg.fireproof_brick": "Огнеупорный кирпич",
"item.tfmg.fire_extinguisher": "Огнетушитель",
"item.tfmg.fire_extinguisher.tooltip.summary": "Использует углекислый газ для тушения пожаров",
"item.tfmg.flamethrower": "Огнемёт",
"item.tfmg.flamethrower.tooltip.behaviour1": "_Выпускает струю пламени_.",
"item.tfmg.flamethrower.tooltip.behaviour2": "Заправляется _топливом_ из бака. Вид топлива влияет на _дальнобойность_ и _разброс_.",
@@ -982,20 +986,12 @@
"item.tfmg.yellow_multimeter.tooltip.summary": "Отображает данные об электроприборе и сети, к которой он подключён.",
"item.tfmg.zinc_electrode": "Цинковый электрод",
"item.tfmg.zinc_grenade": "Цинковая граната",
"tag.fluid.tfmg.blast_stove_fuel": "Топливо для доменного воздухонагревателя",
"tag.fluid.tfmg.firebox_fuel": "Топливо для топки",
"tag.fluid.tfmg.flammable": "Горючие жидкости",
"tag.fluid.tfmg.gas": "Топливо",
"tag.item.tfmg.blast_furnace_fuel": "Топливо для доменной печи",
"tag.item.tfmg.flux": "Флюс",
"tag.item.tfmg.rods": "Стержни",
"tag.item.tfmg.spools": "Катушки",
"tag.item.tfmg.stone_types.bauxite": "Бокситовые камни",
"tag.item.tfmg.stone_types.galena": "Галенитовые камни",
"tfmg.keyinfo.custom_button": "Настраиваемая кнопка контроллера двигателя",
"tfmg.keyinfo.engine_start": "Запуск двигателя",
"tfmg.keyinfo.transmission_shift_down": "Понижение передачи",
"tfmg.keyinfo.transmission_shift_up": "Повышение передачи",
"tfmg.ponder.arc_furnace.header": "Дуговой печью",
"tfmg.ponder.arc_furnace.text_1": "Три графитовых электрода позволят создать дуговую печь — электрический аналог доменной печи",
"tfmg.ponder.blast_furnace.header": "Доменным процессом",
"tfmg.ponder.blast_furnace.text_1": "Основной блок доменной печи — это её лётка, то есть выход для продуктов плавки",
"tfmg.ponder.blast_furnace.text_2": "Для постройки доменной печи возведите трубу из огнеупорного кирпича, с одним люком доменной печи в стенке",
@@ -1011,7 +1007,7 @@
"tfmg.ponder.chemical_vat.text_4": "Вместо лопастей в промышленный смешиватель можно установить центрифугу",
"tfmg.ponder.chemical_vat.text_5": "Для некоторых процессов требуется нагрев",
"tfmg.ponder.chemical_vat.text_6": "Подключение к реактору двух электродных держателей с медными или цинковыми электродами превратит его в электролизёр",
"tfmg.ponder.chemical_vat.text_7": "3 графитовых электрода позволят создать дуговую печь — электрический аналог доменной печи",
"tfmg.ponder.chemical_vat.text_7": "Три графитовых электрода позволят создать дуговую печь — электрический аналог доменной печи",
"tfmg.ponder.coke_oven.header": "Коксованием",
"tfmg.ponder.coke_oven.text_1": "Коксовая печь производит кокс из каменного угля и древесный уголь из древесины",
"tfmg.ponder.coke_oven.text_2": "Процесс коксования длительный, так что имеет смысл строить целые батареи коксовых печей",
@@ -1044,6 +1040,8 @@
"tfmg.ponder.electricity_two.text_5": "Другой прибор — потенциометр, с его помощью можно задать выходное напряжение в процентах от входного",
"tfmg.ponder.electricity_two.text_6": "Выключатель разрывает передачу электроэнергии при получении редстоун-сигнала",
"tfmg.ponder.electricity_two.text_7": "Трансформатор повышает или понижает напряжение пропорционально соотношению витков первичной и вторичной обмоток",
"tfmg.ponder.electrolysis.header": "Электролизом",
"tfmg.ponder.electrolysis.text_1": "Подключение к реактору двух электродных держателей с медными или цинковыми электродами превратит его в электролизёр",
"tfmg.ponder.engines.header": "Двигателями",
"tfmg.ponder.engines.text_1": "Для постройки двигателя разместите до 5 блоков двигателя в ряд",
"tfmg.ponder.engines.text_2": "Подсказки позволят узнать, какие компоненты нужно установить в процессе сборки",
@@ -1054,13 +1052,18 @@
"tfmg.ponder.engines.text_7": "Каждый блок двигателя может быть улучшен установкой на него разных предметов с помощью ПКМ",
"tfmg.ponder.engines.text_8": "Например, промышленные трубы позволят двигателю самостоятельно забирать топливо из расположенного рядом бака",
"tfmg.ponder.engines.text_9": "Для запуска двигателя подайте редстоун-сигнал",
"tfmg.ponder.industrial_mixer.header": "Промышленным смешивателем",
"tfmg.ponder.industrial_mixer.text_1": "Промышленный смешиватель — механический компонент для химического реактора",
"tfmg.ponder.industrial_mixer.text_2": "При установке в него лопастей реактор начнёт работать как смешиватель",
"tfmg.ponder.industrial_mixer.text_3": "Вместо лопастей можно установить центрифугу",
"tfmg.ponder.pumpjack.header": "Добычей нефти",
"tfmg.ponder.pumpjack.text_1": "Чтобы начать добычу нефти, постройте колонну промышленных труб от месторождения до места размещения насоса",
"tfmg.ponder.pumpjack.text_2": "Разместите оголовок скважины на колонне труб — он будет основой нефтяной скважины",
"tfmg.ponder.pumpjack.text_3": "Разместите за ним стойку насоса-качалки",
"tfmg.ponder.pumpjack.text_4": "Далее разместите над оголовком скважины головку балансира, а с противоположной стороны — шарнир балансира",
"tfmg.ponder.pumpjack.text_5": "Соедините головку и шарнир, построив сам балансир из сегментов",
"tfmg.ponder.pumpjack.text_6": "Наконец, разместите снизу от шарнира балансира машинный ввод (к которому будет подведено вращение для работы), а на него — кривошип насоса. Склейте балансир суперклеем, и насос будет собран",
"tfmg.ponder.pumpjack.text_6": "Не забудьте склеить балансир суперклеем",
"tfmg.ponder.pumpjack.text_7": "Наконец, разместите снизу от шарнира балансира машинный ввод (к которому будет подведено вращение для работы), а на него — кривошип насоса",
"tfmg.ponder.shared.behaviour_modify_value_panel": "Поведение можно изменить с помощью меню выбора значений",
"tfmg.ponder.shared.movement_anchors": "С помощью суперклея можно перемещать крупные структуры.",
"tfmg.ponder.shared.rpm16": "16 об/мин",
@@ -1079,17 +1082,9 @@
"tfmg.ponder.tag.oil_processing": "Нефтепереработкой",
"tfmg.ponder.tag.oil_processing.description": "Блоки, применяемые для добычи и переработки нефти",
"tfmg.subtitle.diesel_engine_sounds": "Шум дизельного двигателя",
"tfmg.subtitle.electric_hum": "Электрический гул",
"tfmg.subtitle.engine_sounds": "Шум двигателя",
"entity.tfmg.dry_ice_flake": "Крошка сухого льда",
"item.tfmg.fire_extinguisher": "Огнетушитель",
"item.tfmg.fire_extinguisher.tooltip.summary": "Использует углекислый газ для тушения пожаров",
"tfmg.ponder.arc_furnace.header": "Arc Furnace",
"tfmg.ponder.arc_furnace.text_1": "3 Graphite Electrodes create an Arc Furnace",
"tfmg.ponder.electrolysis.header": "Electrolysis",
"tfmg.ponder.electrolysis.text_1": "Placing 2 electrode holders with Copper or Zinc Electrodes creates an Electrolyzer",
"tfmg.ponder.industrial_mixer.header": "Industrial Mixer",
"tfmg.ponder.industrial_mixer.text_1": "The Industrial Mixer is a machine attachment for the Chemical Vat",
"tfmg.ponder.industrial_mixer.text_2": "When the Mixer Blade is inserted, the vat becomes a Mixer",
"tfmg.ponder.industrial_mixer.text_3": "The Industrial Mixer can also become a Centrifuge",
"tfmg.ponder.pumpjack.text_7": "The last step is placing a machine input (which is the power input for the pumpjack) with a pumpjack crank above it"
"tfmg.subtitle.generator_hum": "Гул генератора",
"tfmg.subtitle.switch_off": "Выключатель разомкнут",
"tfmg.subtitle.switch_on": "Выключатель замкнут"
}

View File

@@ -19,5 +19,45 @@
}
],
"subtitle": "tfmg.subtitle.diesel_engine_sounds"
},
"electric_hum": {
"sounds": [
{
"name": "tfmg:electric_hum",
"type": "file",
"attenuation_distance": 16
}
],
"subtitle": "tfmg.subtitle.electric_hum"
},
"generator_hum": {
"sounds": [
{
"name": "tfmg:generator_hum",
"type": "file",
"attenuation_distance": 16
}
],
"subtitle": "tfmg.subtitle.generator_hum"
},
"switch_on": {
"sounds": [
{
"name": "tfmg:switch_on",
"type": "file",
"attenuation_distance": 16
}
],
"subtitle": "tfmg.subtitle.switch_on"
},
"switch_off": {
"sounds": [
{
"name": "tfmg:switch_off",
"type": "file",
"attenuation_distance": 16
}
],
"subtitle": "tfmg.subtitle.switch_off"
}
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.