This commit is contained in:
DrMangoTea
2024-07-04 20:47:50 +02:00
parent dd72e37691
commit b7a62684b8
1432 changed files with 45229 additions and 0 deletions

View File

@@ -0,0 +1,80 @@
package com.drmangotea.createindustry.base;
import com.drmangotea.createindustry.registry.TFMGParticleTypes;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.math.Quaternion;
import com.mojang.math.Vector3f;
import com.simibubi.create.AllParticleTypes;
import com.simibubi.create.content.equipment.bell.BasicParticleData;
import com.simibubi.create.content.equipment.bell.CustomRotationParticle;
import com.simibubi.create.content.equipment.bell.SoulPulseEffect;
import net.minecraft.client.Camera;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.particle.SpriteSet;
import net.minecraft.core.BlockPos;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.particles.ParticleType;
public class ElectricSparkParticle extends CustomRotationParticle {
private final SpriteSet animatedSprite;
protected int startTicks;
protected int endTicks;
protected int numLoops;
protected int startFrames = 17;
protected int loopFrames = 16;
protected int endFrames = 20;
protected int totalFrames = 53;
public ElectricSparkParticle(ClientLevel worldIn, double x, double y, double z, double vx, double vy, double vz,
SpriteSet spriteSet, ParticleOptions data) {
super(worldIn, x, y, z, spriteSet, 0);
this.animatedSprite = spriteSet;
this.quadSize = 0.5f;
this.setSize(this.quadSize, this.quadSize);
this.loopLength = loopFrames + (int) (this.random.nextFloat() * 5f - 4f);
this.startTicks = startFrames + (int) (this.random.nextFloat() * 5f - 4f);
this.endTicks = endFrames + (int) (this.random.nextFloat() * 5f - 4f);
this.numLoops = (int) (1f + this.random.nextFloat() * 2f);
this.setFrame(0);
this.mirror = this.random.nextBoolean();
}
public void setFrame(int frame) {
if (frame >= 0 && frame < totalFrames)
setSprite(animatedSprite.get(frame, totalFrames));
}
public static class Data extends BasicParticleData<ElectricSparkParticle> {
@Override
public IBasicParticleFactory<ElectricSparkParticle> getBasicFactory() {
return (worldIn, x, y, z, vx, vy, vz, spriteSet) -> new ElectricSparkParticle(worldIn, x, y, z, vx, vy, vz,
spriteSet, this);
}
@Override
public ParticleType<?> getType() {
return TFMGParticleTypes.ELECTRIC_SPARK.get();
}
}
}

View File

@@ -0,0 +1,28 @@
package com.drmangotea.createindustry.base;
import com.tterrag.registrate.AbstractRegistrate;
import com.tterrag.registrate.builders.BuilderCallback;
import com.tterrag.registrate.builders.FluidBuilder;
import com.tterrag.registrate.util.nullness.NonNullFunction;
import com.tterrag.registrate.util.nullness.NonNullSupplier;
import net.minecraft.resources.ResourceLocation;
import net.minecraftforge.fluids.ForgeFlowingFluid;
import net.minecraftforge.fluids.ForgeFlowingFluid.Properties;
public class GasFluidBuilder<T extends ForgeFlowingFluid, P> extends FluidBuilder<T, P> {
public GasFluidBuilder(AbstractRegistrate<?> owner, P parent, String name, BuilderCallback callback,
ResourceLocation stillTexture, ResourceLocation flowingTexture, FluidBuilder.FluidTypeFactory typeFactory,
NonNullFunction<Properties, T> factory) {
super(owner, parent, name, callback, stillTexture, flowingTexture, typeFactory, factory);
source(factory);
}
@Override
public NonNullSupplier<T> asSupplier() {
return this::getEntry;
}
}

View File

@@ -0,0 +1,176 @@
package com.drmangotea.createindustry.base;
import com.drmangotea.createindustry.blocks.encased.TFMGEncasedCogwheelBlock;
import com.drmangotea.createindustry.blocks.encased.TFMGEncasedShaftBlock;
import com.drmangotea.createindustry.registry.TFMGBlocks;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.content.decoration.encasing.EncasingRegistry;
import com.simibubi.create.content.kinetics.simpleRelays.encased.EncasedCogCTBehaviour;
import com.simibubi.create.foundation.data.CreateRegistrate;
import com.simibubi.create.foundation.utility.Couple;
import com.tterrag.registrate.util.entry.BlockEntry;
import net.minecraft.world.level.material.MaterialColor;
import static com.drmangotea.createindustry.CreateTFMG.REGISTRATE;
import static com.drmangotea.createindustry.blocks.encased.TFMGEncasedCogwheelBlock.*;
import static com.simibubi.create.foundation.data.TagGen.axeOrPickaxe;
public class TFMGEncasedBlocks {
public static final BlockEntry<TFMGEncasedShaftBlock> STEEL_ENCASED_SHAFT =
REGISTRATE.block("steel_encased_shaft", p -> new TFMGEncasedShaftBlock(p, TFMGBlocks.STEEL_CASING::get))
.properties(p -> p.color(MaterialColor.PODZOL))
.transform(TFMGBuilderTransformers.encasedShaft("steel", () -> TFMGSpriteShifts.STEEL_CASING))
// .transform(EncasingRegistry.addVariantTo(AllBlocks.SHAFT))
.transform(axeOrPickaxe())
.register();
public static final BlockEntry<TFMGEncasedShaftBlock> HEAVY_CASING_ENCASED_SHAFT =
REGISTRATE.block("heavy_casing_encased_shaft", p -> new TFMGEncasedShaftBlock(p, TFMGBlocks.HEAVY_MACHINERY_CASING::get))
.properties(p -> p.color(MaterialColor.COLOR_GRAY))
.transform(TFMGBuilderTransformers.encasedShaft("heavy_casing", () -> TFMGSpriteShifts.HEAVY_MACHINERY_CASING))
//.transform(EncasingRegistry.addVariantTo(AllBlocks.SHAFT))
.transform(axeOrPickaxe())
.register();
/////////
public static final BlockEntry<TFMGEncasedCogwheelBlock> STEEL_ENCASED_COGWHEEL =
REGISTRATE.block("steel_encased_cogwheel", p -> regular(p, false, TFMGBlocks.STEEL_CASING::get))
.properties(p -> p.color(MaterialColor.PODZOL))
.transform(TFMGBuilderTransformers.encasedCogwheel("steel", () -> TFMGSpriteShifts.STEEL_CASING))
// .transform(EncasingRegistry.addVariantTo(AllBlocks.COGWHEEL))
.onRegister(CreateRegistrate.connectedTextures(() -> new EncasedCogCTBehaviour(TFMGSpriteShifts.STEEL_CASING,
Couple.create(TFMGSpriteShifts.STEEL_ENCASED_COGWHEEL_SIDE,
TFMGSpriteShifts.STEEL_ENCASED_COGWHEEL_OTHERSIDE))))
.transform(axeOrPickaxe())
.register();
public static final BlockEntry<TFMGEncasedCogwheelBlock> HEAVY_CASING_ENCASED_COGWHEEL =
REGISTRATE.block("heavy_casing_encased_cogwheel", p -> regular(p, false, TFMGBlocks.HEAVY_MACHINERY_CASING::get))
.properties(p -> p.color(MaterialColor.COLOR_GRAY))
.transform(TFMGBuilderTransformers.encasedCogwheel("heavy_casing", () -> TFMGSpriteShifts.HEAVY_MACHINERY_CASING))
// .transform(EncasingRegistry.addVariantTo(AllBlocks.COGWHEEL))
.onRegister(CreateRegistrate.connectedTextures(() -> new EncasedCogCTBehaviour(TFMGSpriteShifts.HEAVY_MACHINERY_CASING,
Couple.create(TFMGSpriteShifts.HEAVY_CASING_ENCASED_COGWHEEL_SIDE,
TFMGSpriteShifts.HEAVY_CASING_ENCASED_COGWHEEL_OTHERSIDE))))
.transform(axeOrPickaxe())
.register();
//////
public static final BlockEntry<TFMGEncasedCogwheelBlock> STEEL_ENCASED_LARGE_COGWHEEL = REGISTRATE
.block("steel_encased_large_cogwheel",
p -> regular(p, true, TFMGBlocks.STEEL_CASING::get))
.properties(p -> p.color(MaterialColor.PODZOL))
.transform(TFMGBuilderTransformers.encasedLargeCogwheel("steel", () -> TFMGSpriteShifts.STEEL_CASING))
// .transform(EncasingRegistry.addVariantTo(AllBlocks.LARGE_COGWHEEL))
.transform(axeOrPickaxe())
.register();
public static final BlockEntry<TFMGEncasedCogwheelBlock> HEAVY_CASING_ENCASED_LARGE_COGWHEEL = REGISTRATE
.block("heavy_casing_encased_large_cogwheel", p -> regular(p, true, TFMGBlocks.HEAVY_MACHINERY_CASING::get))
.properties(p -> p.color(MaterialColor.TERRACOTTA_BROWN))
.transform(TFMGBuilderTransformers.encasedLargeCogwheel("heavy_casing", () -> TFMGSpriteShifts.HEAVY_MACHINERY_CASING))
// .transform(EncasingRegistry.addVariantTo(AllBlocks.LARGE_COGWHEEL))
.transform(axeOrPickaxe())
.register();
/////////////
public static final BlockEntry<TFMGEncasedCogwheelBlock> STEEL_ENCASED_STEEL_COGWHEEL =
REGISTRATE.block("steel_encased_steel_cogwheel", p -> steel(p, false, TFMGBlocks.STEEL_CASING::get))
.properties(p -> p.color(MaterialColor.PODZOL))
.transform(TFMGBuilderTransformers.encasedCogwheel("steel", () -> TFMGSpriteShifts.STEEL_CASING))
.transform(EncasingRegistry.addVariantTo(TFMGBlocks.STEEL_COGWHEEL))
.onRegister(CreateRegistrate.connectedTextures(() -> new EncasedCogCTBehaviour(TFMGSpriteShifts.STEEL_CASING,
Couple.create(TFMGSpriteShifts.STEEL_ENCASED_COGWHEEL_SIDE,
TFMGSpriteShifts.STEEL_ENCASED_COGWHEEL_OTHERSIDE))))
.transform(axeOrPickaxe())
.register();
public static final BlockEntry<TFMGEncasedCogwheelBlock> HEAVY_CASING_ENCASED_STEEL_COGWHEEL =
REGISTRATE.block("heavy_casing_encased_steel_cogwheel", p -> steel(p, false, TFMGBlocks.HEAVY_MACHINERY_CASING::get))
.properties(p -> p.color(MaterialColor.COLOR_GRAY))
.transform(TFMGBuilderTransformers.encasedCogwheel("heavy_casing", () -> TFMGSpriteShifts.HEAVY_MACHINERY_CASING))
.transform(EncasingRegistry.addVariantTo(TFMGBlocks.STEEL_COGWHEEL))
.onRegister(CreateRegistrate.connectedTextures(() -> new EncasedCogCTBehaviour(TFMGSpriteShifts.HEAVY_MACHINERY_CASING,
Couple.create(TFMGSpriteShifts.HEAVY_CASING_ENCASED_COGWHEEL_SIDE,
TFMGSpriteShifts.HEAVY_CASING_ENCASED_COGWHEEL_OTHERSIDE))))
.transform(axeOrPickaxe())
.register();
//////
public static final BlockEntry<TFMGEncasedCogwheelBlock> STEEL_ENCASED_LARGE_STEEL_COGWHEEL = REGISTRATE
.block("steel_encased_large_steel_cogwheel",
p -> steel(p, true, TFMGBlocks.STEEL_CASING::get))
.properties(p -> p.color(MaterialColor.PODZOL))
.transform(TFMGBuilderTransformers.encasedLargeCogwheel("steel", () -> TFMGSpriteShifts.STEEL_CASING))
.transform(EncasingRegistry.addVariantTo(TFMGBlocks.LARGE_STEEL_COGWHEEL))
.transform(axeOrPickaxe())
.register();
public static final BlockEntry<TFMGEncasedCogwheelBlock> HEAVY_CASING_ENCASED_LARGE_STEEL_COGWHEEL = REGISTRATE
.block("heavy_casing_encased_large_steel_cogwheel", p -> steel(p, true, TFMGBlocks.HEAVY_MACHINERY_CASING::get))
.properties(p -> p.color(MaterialColor.TERRACOTTA_BROWN))
.transform(TFMGBuilderTransformers.encasedLargeCogwheel("heavy_casing", () -> TFMGSpriteShifts.HEAVY_MACHINERY_CASING))
.transform(EncasingRegistry.addVariantTo(TFMGBlocks.LARGE_STEEL_COGWHEEL))
.transform(axeOrPickaxe())
.register();
////////////////////////////
public static final BlockEntry<TFMGEncasedCogwheelBlock> STEEL_ENCASED_ALUMINUM_COGWHEEL =
REGISTRATE.block("steel_encased_aluminum_cogwheel", p -> aluminum(p, false, TFMGBlocks.STEEL_CASING::get))
.properties(p -> p.color(MaterialColor.PODZOL))
.transform(TFMGBuilderTransformers.encasedCogwheel("steel", () -> TFMGSpriteShifts.STEEL_CASING))
.transform(EncasingRegistry.addVariantTo(TFMGBlocks.ALUMINUM_COGWHEEL))
.onRegister(CreateRegistrate.connectedTextures(() -> new EncasedCogCTBehaviour(TFMGSpriteShifts.STEEL_CASING,
Couple.create(TFMGSpriteShifts.STEEL_ENCASED_COGWHEEL_SIDE,
TFMGSpriteShifts.STEEL_ENCASED_COGWHEEL_OTHERSIDE))))
.transform(axeOrPickaxe())
.register();
public static final BlockEntry<TFMGEncasedCogwheelBlock> HEAVY_CASING_ENCASED_ALUMINUM_COGWHEEL =
REGISTRATE.block("heavy_casing_encased_aluminum_cogwheel", p -> aluminum(p, false, TFMGBlocks.HEAVY_MACHINERY_CASING::get))
.properties(p -> p.color(MaterialColor.COLOR_GRAY))
.transform(TFMGBuilderTransformers.encasedCogwheel("heavy_casing", () -> TFMGSpriteShifts.HEAVY_MACHINERY_CASING))
.transform(EncasingRegistry.addVariantTo(TFMGBlocks.ALUMINUM_COGWHEEL))
.onRegister(CreateRegistrate.connectedTextures(() -> new EncasedCogCTBehaviour(TFMGSpriteShifts.HEAVY_MACHINERY_CASING,
Couple.create(TFMGSpriteShifts.HEAVY_CASING_ENCASED_COGWHEEL_SIDE,
TFMGSpriteShifts.HEAVY_CASING_ENCASED_COGWHEEL_OTHERSIDE))))
.transform(axeOrPickaxe())
.register();
//////
public static final BlockEntry<TFMGEncasedCogwheelBlock> STEEL_ENCASED_LARGE_ALUMINUM_COGWHEEL = REGISTRATE
.block("steel_encased_large_aluminum_cogwheel",
p -> aluminum(p, true, TFMGBlocks.STEEL_CASING::get))
.properties(p -> p.color(MaterialColor.PODZOL))
.transform(TFMGBuilderTransformers.encasedLargeCogwheel("steel", () -> TFMGSpriteShifts.STEEL_CASING))
.transform(EncasingRegistry.addVariantTo(TFMGBlocks.LARGE_ALUMINUM_COGWHEEL))
.transform(axeOrPickaxe())
.register();
public static final BlockEntry<TFMGEncasedCogwheelBlock> HEAVY_CASING_ENCASED_LARGE_ALUMINUM_COGWHEEL = REGISTRATE
.block("heavy_casing_encased_large_aluminum_cogwheel", p -> aluminum(p, true, TFMGBlocks.HEAVY_MACHINERY_CASING::get))
.properties(p -> p.color(MaterialColor.TERRACOTTA_BROWN))
.transform(TFMGBuilderTransformers.encasedLargeCogwheel("heavy_casing", () -> TFMGSpriteShifts.HEAVY_MACHINERY_CASING))
.transform(EncasingRegistry.addVariantTo(TFMGBlocks.LARGE_ALUMINUM_COGWHEEL))
.transform(axeOrPickaxe())
.register();
public static void register() {}
}

View File

@@ -0,0 +1,477 @@
package com.drmangotea.createindustry.base;
import com.drmangotea.createindustry.blocks.pipes.normal.aluminum.AluminumPipeAttachmentModel;
import com.drmangotea.createindustry.blocks.pipes.normal.aluminum.AluminumPipeBlock;
import com.drmangotea.createindustry.blocks.pipes.normal.aluminum.EncasedAluminumPipeBlock;
import com.drmangotea.createindustry.blocks.pipes.normal.aluminum.GlassAluminumPipeBlock;
import com.drmangotea.createindustry.blocks.pipes.normal.brass.BrassPipeAttachmentModel;
import com.drmangotea.createindustry.blocks.pipes.normal.brass.BrassPipeBlock;
import com.drmangotea.createindustry.blocks.pipes.normal.brass.EncasedBrassPipeBlock;
import com.drmangotea.createindustry.blocks.pipes.normal.brass.GlassBrassPipeBlock;
import com.drmangotea.createindustry.blocks.pipes.normal.cast_iron.CastIronPipeAttachmentModel;
import com.drmangotea.createindustry.blocks.pipes.normal.cast_iron.CastIronPipeBlock;
import com.drmangotea.createindustry.blocks.pipes.normal.cast_iron.EncasedCastIronPipeBlock;
import com.drmangotea.createindustry.blocks.pipes.normal.cast_iron.GlassCastIronPipeBlock;
import com.drmangotea.createindustry.blocks.pipes.normal.plastic.EncasedPlasticPipeBlock;
import com.drmangotea.createindustry.blocks.pipes.normal.plastic.GlassPlasticPipeBlock;
import com.drmangotea.createindustry.blocks.pipes.normal.plastic.PlasticPipeAttachmentModel;
import com.drmangotea.createindustry.blocks.pipes.normal.plastic.PlasticPipeBlock;
import com.drmangotea.createindustry.blocks.pipes.normal.steel.EncasedSteelPipeBlock;
import com.drmangotea.createindustry.blocks.pipes.normal.steel.GlassSteelPipeBlock;
import com.drmangotea.createindustry.blocks.pipes.normal.steel.SteelPipeAttachmentModel;
import com.drmangotea.createindustry.blocks.pipes.normal.steel.SteelPipeBlock;
import com.drmangotea.createindustry.blocks.pipes.pumps.TFMGPumpBlock;
import com.drmangotea.createindustry.blocks.pipes.smart_pipes.TFMGSmartFluidPipeBlock;
import com.drmangotea.createindustry.blocks.pipes.valves.TFMGFluidValveBlock;
import com.drmangotea.createindustry.registry.TFMGCreativeModeTabs;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllSpriteShifts;
import com.simibubi.create.content.decoration.encasing.EncasedCTBehaviour;
import com.simibubi.create.content.decoration.encasing.EncasingRegistry;
import com.simibubi.create.content.fluids.pipes.SmartFluidPipeGenerator;
import com.simibubi.create.content.fluids.pipes.valve.FluidValveBlock;
import com.simibubi.create.content.kinetics.BlockStressDefaults;
import com.simibubi.create.foundation.data.AssetLookup;
import com.simibubi.create.foundation.data.BlockStateGen;
import com.simibubi.create.foundation.data.CreateRegistrate;
import com.simibubi.create.foundation.data.SharedProperties;
import com.tterrag.registrate.util.entry.BlockEntry;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.material.MaterialColor;
import net.minecraftforge.client.model.generators.ConfiguredModel;
import static com.drmangotea.createindustry.CreateTFMG.REGISTRATE;
import static com.simibubi.create.foundation.data.ModelGen.customItemModel;
import static com.simibubi.create.foundation.data.TagGen.axeOrPickaxe;
import static com.simibubi.create.foundation.data.TagGen.pickaxeOnly;
public class TFMGPipes {
static {
REGISTRATE.creativeModeTab(() -> TFMGCreativeModeTabs.TFMG_BUILDING_BLOCKS);
}
//STEEL
public static final BlockEntry<SteelPipeBlock> STEEL_PIPE = REGISTRATE.block("steel_pipe", SteelPipeBlock::new)
.initialProperties(() -> Blocks.IRON_BLOCK)
.transform(pickaxeOnly())
.blockstate(BlockStateGen.pipe())
.onRegister(CreateRegistrate.blockModel(() -> SteelPipeAttachmentModel::new))
.item()
.transform(customItemModel())
.register();
public static final BlockEntry<EncasedSteelPipeBlock> COPPER_ENCASED_STEEL_PIPE =
REGISTRATE.block("copper_encased_steel_pipe", p -> new EncasedSteelPipeBlock(p, AllBlocks.COPPER_CASING::get))
.initialProperties(SharedProperties::copperMetal)
.properties(p -> p.color(MaterialColor.TERRACOTTA_LIGHT_GRAY))
.properties(BlockBehaviour.Properties::noOcclusion)
.transform(axeOrPickaxe())
.blockstate(BlockStateGen.encasedPipe())
.onRegister(CreateRegistrate.connectedTextures(() -> new EncasedCTBehaviour(AllSpriteShifts.COPPER_CASING)))
.onRegister(CreateRegistrate.casingConnectivity((block, cc) -> cc.make(block, AllSpriteShifts.COPPER_CASING,
(s, f) -> !s.getValue(EncasedSteelPipeBlock.FACING_TO_PROPERTY_MAP.get(f)))))
.onRegister(CreateRegistrate.blockModel(() -> SteelPipeAttachmentModel::new))
.loot((p, b) -> p.dropOther(b, STEEL_PIPE.get()))
.transform(EncasingRegistry.addVariantTo(TFMGPipes.STEEL_PIPE))
.register();
@SuppressWarnings("removal")
public static final BlockEntry<GlassSteelPipeBlock> GLASS_STEEL_PIPE =
REGISTRATE.block("glass_steel_pipe", GlassSteelPipeBlock::new)
.initialProperties(SharedProperties::copperMetal)
.addLayer(() -> RenderType::cutoutMipped)
.transform(pickaxeOnly())
.blockstate((c, p) -> {
p.getVariantBuilder(c.getEntry())
.forAllStatesExcept(state -> {
Direction.Axis axis = state.getValue(BlockStateProperties.AXIS);
return ConfiguredModel.builder()
.modelFile(p.models()
.getExistingFile(p.modLoc("block/steel_pipe/window")))
.uvLock(false)
.rotationX(axis == Direction.Axis.Y ? 0 : 90)
.rotationY(axis == Direction.Axis.X ? 90 : 0)
.build();
}, BlockStateProperties.WATERLOGGED);
})
.onRegister(CreateRegistrate.blockModel(() -> SteelPipeAttachmentModel::new))
.loot((p, b) -> p.dropOther(b, STEEL_PIPE.get()))
.register();
public static final BlockEntry<TFMGPumpBlock> STEEL_MECHANICAL_PUMP = REGISTRATE.block("steel_mechanical_pump", TFMGPumpBlock::new)
.initialProperties(SharedProperties::copperMetal)
.properties(p -> p.color(MaterialColor.STONE))
.transform(pickaxeOnly())
.blockstate(BlockStateGen.directionalBlockProviderIgnoresWaterlogged(true))
.onRegister(CreateRegistrate.blockModel(() -> SteelPipeAttachmentModel::new))
.transform(BlockStressDefaults.setImpact(4.0))
.item()
.transform(customItemModel())
.register();
public static final BlockEntry<TFMGSmartFluidPipeBlock> STEEL_SMART_FLUID_PIPE =
REGISTRATE.block("steel_smart_fluid_pipe", TFMGSmartFluidPipeBlock::new)
.initialProperties(SharedProperties::copperMetal)
.properties(p -> p.color(MaterialColor.STONE))
.transform(pickaxeOnly())
.blockstate(new SmartFluidPipeGenerator()::generate)
.onRegister(CreateRegistrate.blockModel(() -> SteelPipeAttachmentModel::new))
.item()
.transform(customItemModel())
.register();
public static final BlockEntry<TFMGFluidValveBlock> STEEL_FLUID_VALVE = REGISTRATE.block("steel_fluid_valve", TFMGFluidValveBlock::new)
.initialProperties(SharedProperties::copperMetal)
.transform(pickaxeOnly())
.blockstate((c, p) -> BlockStateGen.directionalAxisBlock(c, p,
(state, vertical) -> AssetLookup.partialBaseModel(c, p, vertical ? "vertical" : "horizontal",
state.getValue(FluidValveBlock.ENABLED) ? "open" : "closed")))
.onRegister(CreateRegistrate.blockModel(() -> SteelPipeAttachmentModel::new))
.item()
.transform(customItemModel())
.register();
//CAST_IRON
public static final BlockEntry<CastIronPipeBlock> CAST_IRON_PIPE = REGISTRATE.block("cast_iron_pipe", CastIronPipeBlock::new)
.initialProperties(() -> Blocks.IRON_BLOCK)
.transform(pickaxeOnly())
.blockstate(BlockStateGen.pipe())
.onRegister(CreateRegistrate.blockModel(() -> CastIronPipeAttachmentModel::new))
.item()
.transform(customItemModel())
.register();
public static final BlockEntry<EncasedCastIronPipeBlock> COPPER_ENCASED_CAST_IRON_PIPE =
REGISTRATE.block("copper_encased_cast_iron_pipe", p -> new EncasedCastIronPipeBlock(p, AllBlocks.COPPER_CASING::get))
.initialProperties(SharedProperties::copperMetal)
.properties(p -> p.color(MaterialColor.TERRACOTTA_LIGHT_GRAY))
.properties(BlockBehaviour.Properties::noOcclusion)
.transform(axeOrPickaxe())
.blockstate(BlockStateGen.encasedPipe())
.onRegister(CreateRegistrate.connectedTextures(() -> new EncasedCTBehaviour(AllSpriteShifts.COPPER_CASING)))
.onRegister(CreateRegistrate.casingConnectivity((block, cc) -> cc.make(block, AllSpriteShifts.COPPER_CASING,
(s, f) -> !s.getValue(EncasedCastIronPipeBlock.FACING_TO_PROPERTY_MAP.get(f)))))
.onRegister(CreateRegistrate.blockModel(() -> CastIronPipeAttachmentModel::new))
.loot((p, b) -> p.dropOther(b, CAST_IRON_PIPE.get()))
.transform(EncasingRegistry.addVariantTo(TFMGPipes.CAST_IRON_PIPE))
.register();
@SuppressWarnings("removal")
public static final BlockEntry<GlassCastIronPipeBlock> GLASS_CAST_IRON_PIPE =
REGISTRATE.block("glass_cast_iron_pipe", GlassCastIronPipeBlock::new)
.initialProperties(SharedProperties::copperMetal)
.addLayer(() -> RenderType::cutoutMipped)
.transform(pickaxeOnly())
.blockstate((c, p) -> {
p.getVariantBuilder(c.getEntry())
.forAllStatesExcept(state -> {
Direction.Axis axis = state.getValue(BlockStateProperties.AXIS);
return ConfiguredModel.builder()
.modelFile(p.models()
.getExistingFile(p.modLoc("block/cast_iron_pipe/window")))
.uvLock(false)
.rotationX(axis == Direction.Axis.Y ? 0 : 90)
.rotationY(axis == Direction.Axis.X ? 90 : 0)
.build();
}, BlockStateProperties.WATERLOGGED);
})
.onRegister(CreateRegistrate.blockModel(() -> CastIronPipeAttachmentModel::new))
.loot((p, b) -> p.dropOther(b, CAST_IRON_PIPE.get()))
.register();
public static final BlockEntry<TFMGPumpBlock> CAST_IRON_MECHANICAL_PUMP = REGISTRATE.block("cast_iron_mechanical_pump", TFMGPumpBlock::new)
.initialProperties(SharedProperties::copperMetal)
.properties(p -> p.color(MaterialColor.STONE))
.transform(pickaxeOnly())
.blockstate(BlockStateGen.directionalBlockProviderIgnoresWaterlogged(true))
.onRegister(CreateRegistrate.blockModel(() -> CastIronPipeAttachmentModel::new))
.transform(BlockStressDefaults.setImpact(4.0))
.item()
.transform(customItemModel())
.register();
public static final BlockEntry<TFMGSmartFluidPipeBlock> CAST_IRON_SMART_FLUID_PIPE =
REGISTRATE.block("cast_iron_smart_fluid_pipe", TFMGSmartFluidPipeBlock::new)
.initialProperties(SharedProperties::copperMetal)
.properties(p -> p.color(MaterialColor.STONE))
.transform(pickaxeOnly())
.blockstate(new SmartFluidPipeGenerator()::generate)
.onRegister(CreateRegistrate.blockModel(() -> CastIronPipeAttachmentModel::new))
.item()
.transform(customItemModel())
.register();
public static final BlockEntry<TFMGFluidValveBlock> CAST_IRON_FLUID_VALVE = REGISTRATE.block("cast_iron_fluid_valve", TFMGFluidValveBlock::new)
.initialProperties(SharedProperties::copperMetal)
.transform(pickaxeOnly())
.blockstate((c, p) -> BlockStateGen.directionalAxisBlock(c, p,
(state, vertical) -> AssetLookup.partialBaseModel(c, p, vertical ? "vertical" : "horizontal",
state.getValue(FluidValveBlock.ENABLED) ? "open" : "closed")))
.onRegister(CreateRegistrate.blockModel(() -> CastIronPipeAttachmentModel::new))
.item()
.transform(customItemModel())
.register();
//BRASS
public static final BlockEntry<BrassPipeBlock> BRASS_PIPE = REGISTRATE.block("brass_pipe", BrassPipeBlock::new)
.initialProperties(() -> Blocks.IRON_BLOCK)
.transform(pickaxeOnly())
.blockstate(BlockStateGen.pipe())
.onRegister(CreateRegistrate.blockModel(() -> BrassPipeAttachmentModel::new))
.item()
.transform(customItemModel())
.register();
public static final BlockEntry<EncasedBrassPipeBlock> COPPER_ENCASED_BRASS_PIPE =
REGISTRATE.block("copper_encased_brass_pipe", p -> new EncasedBrassPipeBlock(p, AllBlocks.COPPER_CASING::get))
.initialProperties(SharedProperties::copperMetal)
.properties(p -> p.color(MaterialColor.TERRACOTTA_LIGHT_GRAY))
.properties(BlockBehaviour.Properties::noOcclusion)
.transform(axeOrPickaxe())
.blockstate(BlockStateGen.encasedPipe())
.onRegister(CreateRegistrate.connectedTextures(() -> new EncasedCTBehaviour(AllSpriteShifts.COPPER_CASING)))
.onRegister(CreateRegistrate.casingConnectivity((block, cc) -> cc.make(block, AllSpriteShifts.COPPER_CASING,
(s, f) -> !s.getValue(EncasedBrassPipeBlock.FACING_TO_PROPERTY_MAP.get(f)))))
.onRegister(CreateRegistrate.blockModel(() -> BrassPipeAttachmentModel::new))
.loot((p, b) -> p.dropOther(b, BRASS_PIPE.get()))
.transform(EncasingRegistry.addVariantTo(TFMGPipes.BRASS_PIPE))
.register();
@SuppressWarnings("removal")
public static final BlockEntry<GlassBrassPipeBlock> GLASS_BRASS_PIPE =
REGISTRATE.block("glass_brass_pipe", GlassBrassPipeBlock::new)
.initialProperties(SharedProperties::copperMetal)
.addLayer(() -> RenderType::cutoutMipped)
.transform(pickaxeOnly())
.blockstate((c, p) -> {
p.getVariantBuilder(c.getEntry())
.forAllStatesExcept(state -> {
Direction.Axis axis = state.getValue(BlockStateProperties.AXIS);
return ConfiguredModel.builder()
.modelFile(p.models()
.getExistingFile(p.modLoc("block/brass_pipe/window")))
.uvLock(false)
.rotationX(axis == Direction.Axis.Y ? 0 : 90)
.rotationY(axis == Direction.Axis.X ? 90 : 0)
.build();
}, BlockStateProperties.WATERLOGGED);
})
.onRegister(CreateRegistrate.blockModel(() -> BrassPipeAttachmentModel::new))
.loot((p, b) -> p.dropOther(b, STEEL_PIPE.get()))
.register();
public static final BlockEntry<TFMGPumpBlock> BRASS_MECHANICAL_PUMP = REGISTRATE.block("brass_mechanical_pump", TFMGPumpBlock::new)
.initialProperties(SharedProperties::copperMetal)
.properties(p -> p.color(MaterialColor.STONE))
.transform(pickaxeOnly())
.blockstate(BlockStateGen.directionalBlockProviderIgnoresWaterlogged(true))
.onRegister(CreateRegistrate.blockModel(() -> BrassPipeAttachmentModel::new))
.transform(BlockStressDefaults.setImpact(4.0))
.item()
.transform(customItemModel())
.register();
public static final BlockEntry<TFMGSmartFluidPipeBlock> BRASS_SMART_FLUID_PIPE =
REGISTRATE.block("brass_smart_fluid_pipe", TFMGSmartFluidPipeBlock::new)
.initialProperties(SharedProperties::copperMetal)
.properties(p -> p.color(MaterialColor.STONE))
.transform(pickaxeOnly())
.blockstate(new SmartFluidPipeGenerator()::generate)
.onRegister(CreateRegistrate.blockModel(() -> BrassPipeAttachmentModel::new))
.item()
.transform(customItemModel())
.register();
public static final BlockEntry<TFMGFluidValveBlock> BRASS_FLUID_VALVE = REGISTRATE.block("brass_fluid_valve", TFMGFluidValveBlock::new)
.initialProperties(SharedProperties::copperMetal)
.transform(pickaxeOnly())
.blockstate((c, p) -> BlockStateGen.directionalAxisBlock(c, p,
(state, vertical) -> AssetLookup.partialBaseModel(c, p, vertical ? "vertical" : "horizontal",
state.getValue(FluidValveBlock.ENABLED) ? "open" : "closed")))
.onRegister(CreateRegistrate.blockModel(() -> BrassPipeAttachmentModel::new))
.item()
.transform(customItemModel())
.register();
//PLASTIC
public static final BlockEntry<PlasticPipeBlock> PLASTIC_PIPE = REGISTRATE.block("plastic_pipe", PlasticPipeBlock::new)
.initialProperties(() -> Blocks.QUARTZ_BLOCK)
.transform(pickaxeOnly())
.blockstate(BlockStateGen.pipe())
.onRegister(CreateRegistrate.blockModel(() -> PlasticPipeAttachmentModel::new))
.item()
.transform(customItemModel())
.register();
public static final BlockEntry<EncasedPlasticPipeBlock> COPPER_ENCASED_PLASTIC_PIPE =
REGISTRATE.block("copper_encased_plastic_pipe", p -> new EncasedPlasticPipeBlock(p, AllBlocks.COPPER_CASING::get))
.initialProperties(SharedProperties::copperMetal)
.properties(p -> p.color(MaterialColor.TERRACOTTA_LIGHT_GRAY))
.properties(BlockBehaviour.Properties::noOcclusion)
.transform(axeOrPickaxe())
.blockstate(BlockStateGen.encasedPipe())
.onRegister(CreateRegistrate.connectedTextures(() -> new EncasedCTBehaviour(AllSpriteShifts.COPPER_CASING)))
.onRegister(CreateRegistrate.casingConnectivity((block, cc) -> cc.make(block, AllSpriteShifts.COPPER_CASING,
(s, f) -> !s.getValue(EncasedPlasticPipeBlock.FACING_TO_PROPERTY_MAP.get(f)))))
.onRegister(CreateRegistrate.blockModel(() -> PlasticPipeAttachmentModel::new))
.loot((p, b) -> p.dropOther(b, PLASTIC_PIPE.get()))
.transform(EncasingRegistry.addVariantTo(TFMGPipes.PLASTIC_PIPE))
.register();
@SuppressWarnings("removal")
public static final BlockEntry<GlassPlasticPipeBlock> GLASS_PLASTIC_PIPE =
REGISTRATE.block("glass_plastic_pipe", GlassPlasticPipeBlock::new)
.initialProperties(SharedProperties::copperMetal)
.addLayer(() -> RenderType::cutoutMipped)
.transform(pickaxeOnly())
.blockstate((c, p) -> {
p.getVariantBuilder(c.getEntry())
.forAllStatesExcept(state -> {
Direction.Axis axis = state.getValue(BlockStateProperties.AXIS);
return ConfiguredModel.builder()
.modelFile(p.models()
.getExistingFile(p.modLoc("block/plastic_pipe/window")))
.uvLock(false)
.rotationX(axis == Direction.Axis.Y ? 0 : 90)
.rotationY(axis == Direction.Axis.X ? 90 : 0)
.build();
}, BlockStateProperties.WATERLOGGED);
})
.onRegister(CreateRegistrate.blockModel(() -> PlasticPipeAttachmentModel::new))
.loot((p, b) -> p.dropOther(b, PLASTIC_PIPE.get()))
.register();
public static final BlockEntry<TFMGPumpBlock> PLASTIC_MECHANICAL_PUMP = REGISTRATE.block("plastic_mechanical_pump", TFMGPumpBlock::new)
.initialProperties(SharedProperties::copperMetal)
.properties(p -> p.color(MaterialColor.STONE))
.transform(pickaxeOnly())
.blockstate(BlockStateGen.directionalBlockProviderIgnoresWaterlogged(true))
.onRegister(CreateRegistrate.blockModel(() -> PlasticPipeAttachmentModel::new))
.transform(BlockStressDefaults.setImpact(4.0))
.item()
.transform(customItemModel())
.register();
public static final BlockEntry<TFMGSmartFluidPipeBlock> PLASTIC_SMART_FLUID_PIPE =
REGISTRATE.block("plastic_smart_fluid_pipe", TFMGSmartFluidPipeBlock::new)
.initialProperties(SharedProperties::copperMetal)
.properties(p -> p.color(MaterialColor.STONE))
.transform(pickaxeOnly())
.blockstate(new SmartFluidPipeGenerator()::generate)
.onRegister(CreateRegistrate.blockModel(() -> PlasticPipeAttachmentModel::new))
.item()
.transform(customItemModel())
.register();
public static final BlockEntry<TFMGFluidValveBlock> PLASTIC_FLUID_VALVE = REGISTRATE.block("plastic_fluid_valve", TFMGFluidValveBlock::new)
.initialProperties(SharedProperties::copperMetal)
.transform(pickaxeOnly())
.blockstate((c, p) -> BlockStateGen.directionalAxisBlock(c, p,
(state, vertical) -> AssetLookup.partialBaseModel(c, p, vertical ? "vertical" : "horizontal",
state.getValue(FluidValveBlock.ENABLED) ? "open" : "closed")))
.onRegister(CreateRegistrate.blockModel(() -> PlasticPipeAttachmentModel::new))
.item()
.transform(customItemModel())
.register();
//ALUMINUM
public static final BlockEntry<AluminumPipeBlock> ALUMINUM_PIPE = REGISTRATE.block("aluminum_pipe", AluminumPipeBlock::new)
.initialProperties(() -> Blocks.IRON_BLOCK)
.transform(pickaxeOnly())
.blockstate(BlockStateGen.pipe())
.onRegister(CreateRegistrate.blockModel(() -> AluminumPipeAttachmentModel::new))
.item()
.transform(customItemModel())
.register();
public static final BlockEntry<EncasedAluminumPipeBlock> COPPER_ENCASED_ALUMINUM_PIPE =
REGISTRATE.block("copper_encased_aluminum_pipe", p -> new EncasedAluminumPipeBlock(p, AllBlocks.COPPER_CASING::get))
.initialProperties(SharedProperties::copperMetal)
.properties(p -> p.color(MaterialColor.TERRACOTTA_LIGHT_GRAY))
.properties(BlockBehaviour.Properties::noOcclusion)
.transform(axeOrPickaxe())
.blockstate(BlockStateGen.encasedPipe())
.onRegister(CreateRegistrate.connectedTextures(() -> new EncasedCTBehaviour(AllSpriteShifts.COPPER_CASING)))
.onRegister(CreateRegistrate.casingConnectivity((block, cc) -> cc.make(block, AllSpriteShifts.COPPER_CASING,
(s, f) -> !s.getValue(EncasedAluminumPipeBlock.FACING_TO_PROPERTY_MAP.get(f)))))
.onRegister(CreateRegistrate.blockModel(() -> AluminumPipeAttachmentModel::new))
.loot((p, b) -> p.dropOther(b, ALUMINUM_PIPE.get()))
.transform(EncasingRegistry.addVariantTo(TFMGPipes.ALUMINUM_PIPE))
.register();
@SuppressWarnings("removal")
public static final BlockEntry<GlassAluminumPipeBlock> GLASS_ALUMINUM_PIPE =
REGISTRATE.block("glass_aluminum_pipe", GlassAluminumPipeBlock::new)
.initialProperties(SharedProperties::copperMetal)
.addLayer(() -> RenderType::cutoutMipped)
.transform(pickaxeOnly())
.blockstate((c, p) -> {
p.getVariantBuilder(c.getEntry())
.forAllStatesExcept(state -> {
Direction.Axis axis = state.getValue(BlockStateProperties.AXIS);
return ConfiguredModel.builder()
.modelFile(p.models()
.getExistingFile(p.modLoc("block/aluminum_pipe/window")))
.uvLock(false)
.rotationX(axis == Direction.Axis.Y ? 0 : 90)
.rotationY(axis == Direction.Axis.X ? 90 : 0)
.build();
}, BlockStateProperties.WATERLOGGED);
})
.onRegister(CreateRegistrate.blockModel(() -> AluminumPipeAttachmentModel::new))
.loot((p, b) -> p.dropOther(b, ALUMINUM_PIPE.get()))
.register();
public static final BlockEntry<TFMGPumpBlock> ALUMINUM_MECHANICAL_PUMP = REGISTRATE.block("aluminum_mechanical_pump", TFMGPumpBlock::new)
.initialProperties(SharedProperties::copperMetal)
.properties(p -> p.color(MaterialColor.STONE))
.transform(pickaxeOnly())
.blockstate(BlockStateGen.directionalBlockProviderIgnoresWaterlogged(true))
.onRegister(CreateRegistrate.blockModel(() -> AluminumPipeAttachmentModel::new))
.transform(BlockStressDefaults.setImpact(4.0))
.item()
.transform(customItemModel())
.register();
public static final BlockEntry<TFMGSmartFluidPipeBlock> ALUMINUM_SMART_FLUID_PIPE =
REGISTRATE.block("aluminum_smart_fluid_pipe", TFMGSmartFluidPipeBlock::new)
.initialProperties(SharedProperties::copperMetal)
.properties(p -> p.color(MaterialColor.STONE))
.transform(pickaxeOnly())
.blockstate(new SmartFluidPipeGenerator()::generate)
.onRegister(CreateRegistrate.blockModel(() -> AluminumPipeAttachmentModel::new))
.item()
.transform(customItemModel())
.register();
public static final BlockEntry<TFMGFluidValveBlock> ALUMINUM_FLUID_VALVE = REGISTRATE.block("aluminum_fluid_valve", TFMGFluidValveBlock::new)
.initialProperties(SharedProperties::copperMetal)
.transform(pickaxeOnly())
.blockstate((c, p) -> BlockStateGen.directionalAxisBlock(c, p,
(state, vertical) -> AssetLookup.partialBaseModel(c, p, vertical ? "vertical" : "horizontal",
state.getValue(FluidValveBlock.ENABLED) ? "open" : "closed")))
.onRegister(CreateRegistrate.blockModel(() -> AluminumPipeAttachmentModel::new))
.item()
.transform(customItemModel())
.register();
static {
REGISTRATE.creativeModeTab(() -> TFMGCreativeModeTabs.TFMG_BASE);
}
public static void register(){}
}

View File

@@ -0,0 +1,27 @@
package com.drmangotea.createindustry.base;
import net.minecraft.core.BlockPos;
public class TFMGTools {
public static float getDistance(BlockPos pos1, BlockPos pos2,boolean _2D){
float x = Math.abs(pos1.getX()-pos2.getX());
float y = Math.abs(pos1.getY()-pos2.getY());
float z = Math.abs(pos1.getZ()-pos2.getZ());
float distance2D = (float) Math.sqrt(x*x+z*z);
if(_2D)
return distance2D;
return (float) Math.sqrt(distance2D*distance2D+y*y);
}
}

View File

@@ -0,0 +1,21 @@
package com.drmangotea.createindustry.base.effects;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectCategory;
import net.minecraft.world.entity.LivingEntity;
public class HellFireEffect extends MobEffect {
public HellFireEffect(MobEffectCategory pCategory, int pColor) {
super(pCategory, pColor);
}
@Override
public void applyEffectTick(LivingEntity pLivingEntity, int pAmplifier) {
pLivingEntity.setSecondsOnFire(1);
}
@Override
public boolean isDurationEffectTick(int pDuration, int pAmplifier) {
return true;
}
}

View File

@@ -0,0 +1,73 @@
package com.drmangotea.createindustry.base.util;
import com.drmangotea.createindustry.base.ElectricSparkParticle;
import com.drmangotea.createindustry.base.util.spark.Spark;
import com.drmangotea.createindustry.registry.TFMGEntityTypes;
import com.simibubi.create.Create;
import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.core.BlockPos;
import net.minecraft.util.Mth;
import net.minecraft.util.RandomSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Explosion;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
import org.apache.commons.lang3.StringUtils;
import java.util.Arrays;
import java.util.stream.Collectors;
public class TFMGUtils {
public static void createFireExplosion(Level level, Entity entity, BlockPos pos, int sparkAmount, float radius) {
if (level.isClientSide&&entity!=null)
level.broadcastEntityEvent(entity, (byte) 3);
for (int i = 0; i < sparkAmount; i++) {
float x = Create.RANDOM.nextFloat(360);
float y = Create.RANDOM.nextFloat(360);
float z = Create.RANDOM.nextFloat(360);
Spark spark = TFMGEntityTypes.SPARK.create(level);
spark.moveTo(pos.getX(), pos.getY() + 1, pos.getZ());
float f = -Mth.sin(y * ((float) Math.PI / 180F)) * Mth.cos(x * ((float) Math.PI / 180F));
float f1 = -Mth.sin((x + z) * ((float) Math.PI / 180F));
float f2 = Mth.cos(y * ((float) Math.PI / 180F)) * Mth.cos(x * ((float) Math.PI / 180F));
spark.shoot(f, f1, f2, 0.3f, 1);
level.addFreshEntity(spark);
}
level.explode(null, pos.getX(), pos.getY(), pos.getZ(), radius, Explosion.BlockInteraction.BREAK);
}
public static String fromId(String key) {
String s = key.replaceAll("_", " ");
s = Arrays.stream(StringUtils.splitByCharacterTypeCamelCase(s)).map(StringUtils::capitalize).collect(Collectors.joining(" "));
s = StringUtils.normalizeSpace(s);
return s;
}
public static void spawnElectricParticles(Level level,BlockPos pos) {
if (level == null)
return;
RandomSource r = level.getRandom();
for(int i = 0; i < r.nextInt(40);i++) {
float x = Create.RANDOM.nextFloat(2)-1;
float y = Create.RANDOM.nextFloat(2)-1;
float z = Create.RANDOM.nextFloat(2)-1;
level.addParticle(new ElectricSparkParticle.Data(), pos.getX() + 0.5f+x, pos.getY() + 0.5f+y, pos.getZ() + 0.5f+z, x, y, z);
}
}
}

View File

@@ -0,0 +1,28 @@
package com.drmangotea.createindustry.blocks;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.kinetics.base.DirectionalKineticBlock;
import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
import com.simibubi.create.content.kinetics.base.KineticBlockEntityRenderer;
import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import net.minecraft.world.level.block.state.BlockState;
public class HalfShaftRenderer<T extends KineticBlockEntity> extends KineticBlockEntityRenderer<T> {
public HalfShaftRenderer(BlockEntityRendererProvider.Context context) {
super(context);
}
@Override
protected SuperByteBuffer getRotatedModel(T be, BlockState state) {
return CachedBufferer.partialFacing(AllPartialModels.SHAFT_HALF, state, state
.getValue(DirectionalKineticBlock.FACING));}
}

View File

@@ -0,0 +1,26 @@
package com.drmangotea.createindustry.blocks;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.HorizontalDirectionalBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
public class TFMGHorizontalDirectionalBlock extends HorizontalDirectionalBlock {
public TFMGHorizontalDirectionalBlock(Properties p_54120_) {
super(p_54120_);
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
builder.add(FACING);
super.createBlockStateDefinition(builder);
}
public BlockState getStateForPlacement(BlockPlaceContext pContext) {
return this.defaultBlockState().setValue(FACING, pContext.getHorizontalDirection().getOpposite());
}
}

View File

@@ -0,0 +1,116 @@
package com.drmangotea.createindustry.blocks.cogwheeels;
import com.drmangotea.createindustry.registry.TFMGPartialModels;
import com.jozufozu.flywheel.api.InstanceData;
import com.jozufozu.flywheel.api.Instancer;
import com.jozufozu.flywheel.api.Material;
import com.jozufozu.flywheel.api.MaterialManager;
import com.jozufozu.flywheel.core.PartialModel;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Vector3f;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.kinetics.base.IRotate;
import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
import com.simibubi.create.content.kinetics.base.KineticBlockEntityInstance;
import com.simibubi.create.content.kinetics.base.flwdata.RotatingData;
import com.simibubi.create.content.kinetics.simpleRelays.BracketedKineticBlockEntityRenderer;
import com.simibubi.create.foundation.render.AllMaterialSpecs;
import com.simibubi.create.foundation.utility.Iterate;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import java.util.Optional;
public class EncasedAluminumCogInstance extends KineticBlockEntityInstance<KineticBlockEntity> {
private boolean large;
protected RotatingData rotatingModel;
protected Optional<RotatingData> rotatingTopShaft;
protected Optional<RotatingData> rotatingBottomShaft;
public static EncasedAluminumCogInstance small(MaterialManager modelManager, KineticBlockEntity blockEntity) {
return new EncasedAluminumCogInstance(modelManager, blockEntity, false);
}
public static EncasedAluminumCogInstance large(MaterialManager modelManager, KineticBlockEntity blockEntity) {
return new EncasedAluminumCogInstance(modelManager, blockEntity, true);
}
public EncasedAluminumCogInstance(MaterialManager modelManager, KineticBlockEntity blockEntity, boolean large) {
super(modelManager, blockEntity);
this.large = large;
}
@Override
public void init() {
rotatingModel = setup(getCogModel().createInstance());
Block block = blockState.getBlock();
if (!(block instanceof IRotate))
return;
IRotate def = (IRotate) block;
rotatingTopShaft = Optional.empty();
rotatingBottomShaft = Optional.empty();
for (Direction d : Iterate.directionsInAxis(axis)) {
if (!def.hasShaftTowards(blockEntity.getLevel(), blockEntity.getBlockPos(), blockState, d))
continue;
RotatingData data = setup(getRotatingMaterial().getModel(AllPartialModels.SHAFT_HALF, blockState, d)
.createInstance());
if (large)
data.setRotationOffset(BracketedKineticBlockEntityRenderer.getShaftAngleOffset(axis, pos));
if (d.getAxisDirection() == Direction.AxisDirection.POSITIVE)
rotatingTopShaft = Optional.of(data);
else
rotatingBottomShaft = Optional.of(data);
}
}
@Override
public void update() {
updateRotation(rotatingModel);
rotatingTopShaft.ifPresent(this::updateRotation);
rotatingBottomShaft.ifPresent(this::updateRotation);
}
@Override
public void updateLight() {
relight(pos, rotatingModel);
rotatingTopShaft.ifPresent(d -> relight(pos, d));
rotatingBottomShaft.ifPresent(d -> relight(pos, d));
}
@Override
public void remove() {
rotatingModel.delete();
rotatingTopShaft.ifPresent(InstanceData::delete);
rotatingBottomShaft.ifPresent(InstanceData::delete);
}
protected Instancer<RotatingData> getCogModel() {
BlockState referenceState = blockEntity.getBlockState();
Direction facing =
Direction.fromAxisAndDirection(referenceState.getValue(BlockStateProperties.AXIS), Direction.AxisDirection.POSITIVE);
PartialModel partial = large ? TFMGPartialModels.LARGE_ALUMINUM_COGHWEEL : TFMGPartialModels.ALUMINUM_COGHWEEL;
return getCutoutRotatingMaterial().getModel(partial, referenceState, facing, () -> {
PoseStack poseStack = new PoseStack();
TransformStack.cast(poseStack)
.centre()
.rotateToFace(facing)
.multiply(Vector3f.XN.rotationDegrees(90))
.unCentre();
return poseStack;
});
}
protected Material<RotatingData> getCutoutRotatingMaterial() {
return materialManager.defaultCutout()
.material(AllMaterialSpecs.ROTATING);
}
}

View File

@@ -0,0 +1,74 @@
package com.drmangotea.createindustry.blocks.cogwheeels;
import com.drmangotea.createindustry.registry.TFMGPartialModels;
import com.jozufozu.flywheel.backend.Backend;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.kinetics.base.IRotate;
import com.simibubi.create.content.kinetics.base.KineticBlockEntityRenderer;
import com.simibubi.create.content.kinetics.simpleRelays.BracketedKineticBlockEntityRenderer;
import com.simibubi.create.content.kinetics.simpleRelays.SimpleKineticBlockEntity;
import com.simibubi.create.content.kinetics.simpleRelays.encased.EncasedCogwheelBlock;
import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.utility.Iterate;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
public class EncasedAluminumCogRenderer extends KineticBlockEntityRenderer<SimpleKineticBlockEntity> {
private boolean large;
public static EncasedAluminumCogRenderer small(BlockEntityRendererProvider.Context context) {
return new EncasedAluminumCogRenderer(context, false);
}
public static EncasedAluminumCogRenderer large(BlockEntityRendererProvider.Context context) {
return new EncasedAluminumCogRenderer(context, true);
}
public EncasedAluminumCogRenderer(BlockEntityRendererProvider.Context context, boolean large) {
super(context);
this.large = large;
}
@Override
protected void renderSafe(SimpleKineticBlockEntity be, float partialTicks, PoseStack ms, MultiBufferSource buffer,
int light, int overlay) {
super.renderSafe(be, partialTicks, ms, buffer, light, overlay);
if (Backend.canUseInstancing(be.getLevel()))
return;
BlockState blockState = be.getBlockState();
Block block = blockState.getBlock();
if (!(block instanceof IRotate))
return;
IRotate def = (IRotate) block;
Direction.Axis axis = getRotationAxisOf(be);
BlockPos pos = be.getBlockPos();
float angle = large ? BracketedKineticBlockEntityRenderer.getAngleForLargeCogShaft(be, axis)
: getAngleForTe(be, pos, axis);
for (Direction d : Iterate.directionsInAxis(getRotationAxisOf(be))) {
if (!def.hasShaftTowards(be.getLevel(), be.getBlockPos(), blockState, d))
continue;
SuperByteBuffer shaft = CachedBufferer.partialFacing(AllPartialModels.SHAFT_HALF, be.getBlockState(), d);
kineticRotationTransform(shaft, be, axis, angle, light);
shaft.renderInto(ms, buffer.getBuffer(RenderType.cutoutMipped()));
}
}
@Override
protected SuperByteBuffer getRotatedModel(SimpleKineticBlockEntity be, BlockState state) {
return CachedBufferer.partialFacingVertical(
large ? TFMGPartialModels.LARGE_ALUMINUM_COGHWEEL : TFMGPartialModels.ALUMINUM_COGHWEEL, state,
Direction.fromAxisAndDirection(state.getValue(EncasedCogwheelBlock.AXIS), Direction.AxisDirection.POSITIVE));
}
}

View File

@@ -0,0 +1,111 @@
package com.drmangotea.createindustry.blocks.cogwheeels;
import com.drmangotea.createindustry.registry.TFMGBlockEntities;
import com.drmangotea.createindustry.registry.TFMGPartialModels;
import com.jozufozu.flywheel.api.InstanceData;
import com.jozufozu.flywheel.api.Instancer;
import com.jozufozu.flywheel.api.MaterialManager;
import com.jozufozu.flywheel.core.PartialModel;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Vector3f;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.kinetics.base.IRotate;
import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
import com.simibubi.create.content.kinetics.base.KineticBlockEntityInstance;
import com.simibubi.create.content.kinetics.base.flwdata.RotatingData;
import com.simibubi.create.content.kinetics.simpleRelays.BracketedKineticBlockEntityRenderer;
import com.simibubi.create.foundation.utility.Iterate;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import java.util.Optional;
public class EncasedSteelCogInstance extends KineticBlockEntityInstance<KineticBlockEntity> {
private boolean large;
protected RotatingData rotatingModel;
protected Optional<RotatingData> rotatingTopShaft;
protected Optional<RotatingData> rotatingBottomShaft;
public static EncasedSteelCogInstance small(MaterialManager modelManager, KineticBlockEntity blockEntity) {
return new EncasedSteelCogInstance(modelManager, blockEntity, false);
}
public static EncasedSteelCogInstance large(MaterialManager modelManager, KineticBlockEntity blockEntity) {
return new EncasedSteelCogInstance(modelManager, blockEntity, true);
}
public EncasedSteelCogInstance(MaterialManager modelManager, KineticBlockEntity blockEntity, boolean large) {
super(modelManager, blockEntity);
this.large = large;
}
@Override
public void init() {
rotatingModel = setup(getCogModel().createInstance());
Block block = blockState.getBlock();
if (!(block instanceof IRotate))
return;
IRotate def = (IRotate) block;
rotatingTopShaft = Optional.empty();
rotatingBottomShaft = Optional.empty();
for (Direction d : Iterate.directionsInAxis(axis)) {
if (!def.hasShaftTowards(blockEntity.getLevel(), blockEntity.getBlockPos(), blockState, d))
continue;
RotatingData data = setup(getRotatingMaterial().getModel(AllPartialModels.SHAFT_HALF, blockState, d)
.createInstance());
if (large)
data.setRotationOffset(BracketedKineticBlockEntityRenderer.getShaftAngleOffset(axis, pos));
if (d.getAxisDirection() == Direction.AxisDirection.POSITIVE)
rotatingTopShaft = Optional.of(data);
else
rotatingBottomShaft = Optional.of(data);
}
}
@Override
public void update() {
updateRotation(rotatingModel);
rotatingTopShaft.ifPresent(this::updateRotation);
rotatingBottomShaft.ifPresent(this::updateRotation);
}
@Override
public void updateLight() {
relight(pos, rotatingModel);
rotatingTopShaft.ifPresent(d -> relight(pos, d));
rotatingBottomShaft.ifPresent(d -> relight(pos, d));
}
@Override
public void remove() {
rotatingModel.delete();
rotatingTopShaft.ifPresent(InstanceData::delete);
rotatingBottomShaft.ifPresent(InstanceData::delete);
}
protected Instancer<RotatingData> getCogModel() {
BlockState referenceState = blockEntity.getBlockState();
Direction facing =
Direction.fromAxisAndDirection(referenceState.getValue(BlockStateProperties.AXIS), Direction.AxisDirection.POSITIVE);
PartialModel partial = large ? TFMGPartialModels.LARGE_STEEL_COGHWEEL : TFMGPartialModels.STEEL_COGHWEEL;
return getRotatingMaterial().getModel(partial, referenceState, facing, () -> {
PoseStack poseStack = new PoseStack();
TransformStack.cast(poseStack)
.centre()
.rotateToFace(facing)
.multiply(Vector3f.XN.rotationDegrees(90))
.unCentre();
return poseStack;
});
}
}

View File

@@ -0,0 +1,74 @@
package com.drmangotea.createindustry.blocks.cogwheeels;
import com.drmangotea.createindustry.registry.TFMGPartialModels;
import com.jozufozu.flywheel.backend.Backend;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.kinetics.base.IRotate;
import com.simibubi.create.content.kinetics.base.KineticBlockEntityRenderer;
import com.simibubi.create.content.kinetics.simpleRelays.BracketedKineticBlockEntityRenderer;
import com.simibubi.create.content.kinetics.simpleRelays.SimpleKineticBlockEntity;
import com.simibubi.create.content.kinetics.simpleRelays.encased.EncasedCogwheelBlock;
import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.utility.Iterate;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
public class EncasedSteelCogRenderer extends KineticBlockEntityRenderer<SimpleKineticBlockEntity> {
private boolean large;
public static EncasedSteelCogRenderer small(BlockEntityRendererProvider.Context context) {
return new EncasedSteelCogRenderer(context, false);
}
public static EncasedSteelCogRenderer large(BlockEntityRendererProvider.Context context) {
return new EncasedSteelCogRenderer(context, true);
}
public EncasedSteelCogRenderer(BlockEntityRendererProvider.Context context, boolean large) {
super(context);
this.large = large;
}
@Override
protected void renderSafe(SimpleKineticBlockEntity be, float partialTicks, PoseStack ms, MultiBufferSource buffer,
int light, int overlay) {
super.renderSafe(be, partialTicks, ms, buffer, light, overlay);
if (Backend.canUseInstancing(be.getLevel()))
return;
BlockState blockState = be.getBlockState();
Block block = blockState.getBlock();
if (!(block instanceof IRotate))
return;
IRotate def = (IRotate) block;
Direction.Axis axis = getRotationAxisOf(be);
BlockPos pos = be.getBlockPos();
float angle = large ? BracketedKineticBlockEntityRenderer.getAngleForLargeCogShaft(be, axis)
: getAngleForTe(be, pos, axis);
for (Direction d : Iterate.directionsInAxis(getRotationAxisOf(be))) {
if (!def.hasShaftTowards(be.getLevel(), be.getBlockPos(), blockState, d))
continue;
SuperByteBuffer shaft = CachedBufferer.partialFacing(AllPartialModels.SHAFT_HALF, be.getBlockState(), d);
kineticRotationTransform(shaft, be, axis, angle, light);
shaft.renderInto(ms, buffer.getBuffer(RenderType.cutoutMipped()));
}
}
@Override
protected SuperByteBuffer getRotatedModel(SimpleKineticBlockEntity be, BlockState state) {
return CachedBufferer.partialFacingVertical(
large ? TFMGPartialModels.LARGE_STEEL_COGHWEEL : TFMGPartialModels.STEEL_COGHWEEL, state,
Direction.fromAxisAndDirection(state.getValue(EncasedCogwheelBlock.AXIS), Direction.AxisDirection.POSITIVE));
}
}

View File

@@ -0,0 +1,218 @@
package com.drmangotea.createindustry.blocks.cogwheeels;
import com.drmangotea.createindustry.registry.TFMGBlockEntities;
import com.simibubi.create.*;
import com.simibubi.create.content.decoration.encasing.EncasableBlock;
import com.simibubi.create.content.kinetics.base.IRotate;
import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
import com.simibubi.create.content.kinetics.simpleRelays.AbstractSimpleShaftBlock;
import com.simibubi.create.content.kinetics.simpleRelays.ICogWheel;
import com.simibubi.create.content.kinetics.speedController.SpeedControllerBlock;
import com.simibubi.create.foundation.advancement.AllAdvancements;
import com.simibubi.create.foundation.utility.Iterate;
import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.NonNullList;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.material.Fluids;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
import javax.annotation.ParametersAreNonnullByDefault;
import static net.minecraft.core.Direction.Axis;
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
public class TFMGCogWheelBlock extends AbstractSimpleShaftBlock implements ICogWheel, EncasableBlock {
boolean isLarge;
protected TFMGCogWheelBlock(boolean large, Properties properties) {
super(properties);
isLarge = large;
}
public static TFMGCogWheelBlock small(Properties properties) {
return new TFMGCogWheelBlock(false, properties);
}
public static TFMGCogWheelBlock large(Properties properties) {
return new TFMGCogWheelBlock(true, properties);
}
@Override
public boolean isLargeCog() {
return isLarge;
}
@Override
public boolean isSmallCog() {
return !isLarge;
}
@Override
public void fillItemCategory(CreativeModeTab pTab, NonNullList<ItemStack> pItems) {
super.fillItemCategory(pTab, pItems);
// Ensure the belt item is added after large cogwheels in the creative tab
if (AllBlocks.LARGE_COGWHEEL.is(this) && pTab == AllCreativeModeTabs.BASE_CREATIVE_TAB)
pItems.add(AllItems.BELT_CONNECTOR.asStack());
}
@Override
public VoxelShape getShape(BlockState state, BlockGetter worldIn, BlockPos pos, CollisionContext context) {
return (isLarge ? AllShapes.LARGE_GEAR : AllShapes.SMALL_GEAR).get(state.getValue(AXIS));
}
@Override
public boolean canSurvive(BlockState state, LevelReader worldIn, BlockPos pos) {
return isValidCogwheelPosition(ICogWheel.isLargeCog(state), worldIn, pos, state.getValue(AXIS));
}
@Override
public void setPlacedBy(Level worldIn, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) {
super.setPlacedBy(worldIn, pos, state, placer, stack);
if (placer instanceof Player player)
triggerShiftingGearsAdvancement(worldIn, pos, state, player);
}
protected void triggerShiftingGearsAdvancement(Level world, BlockPos pos, BlockState state, Player player) {
if (world.isClientSide || player == null)
return;
Axis axis = state.getValue(TFMGCogWheelBlock.AXIS);
for (Axis perpendicular1 : Iterate.axes) {
if (perpendicular1 == axis)
continue;
Direction d1 = Direction.get(Direction.AxisDirection.POSITIVE, perpendicular1);
for (Axis perpendicular2 : Iterate.axes) {
if (perpendicular1 == perpendicular2)
continue;
if (axis == perpendicular2)
continue;
Direction d2 = Direction.get(Direction.AxisDirection.POSITIVE, perpendicular2);
for (int offset1 : Iterate.positiveAndNegative) {
for (int offset2 : Iterate.positiveAndNegative) {
BlockPos connectedPos = pos.relative(d1, offset1)
.relative(d2, offset2);
BlockState blockState = world.getBlockState(connectedPos);
if (!(blockState.getBlock() instanceof TFMGCogWheelBlock))
continue;
if (blockState.getValue(TFMGCogWheelBlock.AXIS) != axis)
continue;
if (ICogWheel.isLargeCog(blockState) == isLarge)
continue;
AllAdvancements.COGS.awardTo(player);
}
}
}
}
}
@Override
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand,
BlockHitResult ray) {
if (player.isShiftKeyDown() || !player.mayBuild())
return InteractionResult.PASS;
ItemStack heldItem = player.getItemInHand(hand);
InteractionResult result = tryEncase(state, world, pos, heldItem, player, hand, ray);
if (result.consumesAction())
return result;
return InteractionResult.PASS;
}
public static boolean isValidCogwheelPosition(boolean large, LevelReader worldIn, BlockPos pos, Axis cogAxis) {
for (Direction facing : Iterate.directions) {
if (facing.getAxis() == cogAxis)
continue;
BlockPos offsetPos = pos.relative(facing);
BlockState blockState = worldIn.getBlockState(offsetPos);
if (blockState.hasProperty(AXIS) && facing.getAxis() == blockState.getValue(AXIS))
continue;
if (ICogWheel.isLargeCog(blockState) || large && ICogWheel.isSmallCog(blockState))
return false;
}
return true;
}
protected Axis getAxisForPlacement(BlockPlaceContext context) {
if (context.getPlayer() != null && context.getPlayer()
.isShiftKeyDown())
return context.getClickedFace()
.getAxis();
Level world = context.getLevel();
BlockState stateBelow = world.getBlockState(context.getClickedPos()
.below());
if (AllBlocks.ROTATION_SPEED_CONTROLLER.has(stateBelow) && isLargeCog())
return stateBelow.getValue(SpeedControllerBlock.HORIZONTAL_AXIS) == Axis.X ? Axis.Z : Axis.X;
BlockPos placedOnPos = context.getClickedPos()
.relative(context.getClickedFace()
.getOpposite());
BlockState placedAgainst = world.getBlockState(placedOnPos);
Block block = placedAgainst.getBlock();
if (ICogWheel.isSmallCog(placedAgainst))
return ((IRotate) block).getRotationAxis(placedAgainst);
Axis preferredAxis = getPreferredAxis(context);
return preferredAxis != null ? preferredAxis
: context.getClickedFace()
.getAxis();
}
@Override
public BlockState getStateForPlacement(BlockPlaceContext context) {
boolean shouldWaterlog = context.getLevel()
.getFluidState(context.getClickedPos())
.getType() == Fluids.WATER;
return this.defaultBlockState()
.setValue(AXIS, getAxisForPlacement(context))
.setValue(BlockStateProperties.WATERLOGGED, shouldWaterlog);
}
@Override
public float getParticleTargetRadius() {
return isLargeCog() ? 1.125f : .65f;
}
@Override
public float getParticleInitialRadius() {
return isLargeCog() ? 1f : .75f;
}
@Override
public boolean isDedicatedCogWheel() {
return true;
}
@Override
public BlockEntityType<? extends KineticBlockEntity> getBlockEntityType() {
return TFMGBlockEntities.TFMG_COGWHEEL.get();
}
}

View File

@@ -0,0 +1,311 @@
package com.drmangotea.createindustry.blocks.cogwheeels;
import static com.simibubi.create.content.kinetics.base.RotatedPillarKineticBlock.AXIS;
import java.util.List;
import java.util.function.Predicate;
import com.simibubi.create.AllShapes;
import com.simibubi.create.content.kinetics.base.DirectionalKineticBlock;
import com.simibubi.create.content.kinetics.base.HorizontalKineticBlock;
import com.simibubi.create.content.kinetics.base.IRotate;
import com.simibubi.create.content.kinetics.base.RotatedPillarKineticBlock;
import com.simibubi.create.content.kinetics.simpleRelays.ICogWheel;
import com.simibubi.create.foundation.placement.IPlacementHelper;
import com.simibubi.create.foundation.placement.PlacementHelpers;
import com.simibubi.create.foundation.placement.PlacementOffset;
import com.simibubi.create.foundation.utility.Iterate;
import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Direction.Axis;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
public class TFMGCogwheelBlockItem extends BlockItem {
boolean large;
private final int placementHelperId;
private final int integratedCogHelperId;
public TFMGCogwheelBlockItem(TFMGCogWheelBlock block, Properties builder) {
super(block, builder);
large = block.isLarge;
placementHelperId = PlacementHelpers.register(large ? new LargeCogHelper() : new SmallCogHelper());
integratedCogHelperId =
PlacementHelpers.register(large ? new IntegratedLargeCogHelper() : new IntegratedSmallCogHelper());
}
@Override
public InteractionResult onItemUseFirst(ItemStack stack, UseOnContext context) {
Level world = context.getLevel();
BlockPos pos = context.getClickedPos();
BlockState state = world.getBlockState(pos);
IPlacementHelper helper = PlacementHelpers.get(placementHelperId);
Player player = context.getPlayer();
BlockHitResult ray = new BlockHitResult(context.getClickLocation(), context.getClickedFace(), pos, true);
if (helper.matchesState(state) && player != null && !player.isShiftKeyDown()) {
return helper.getOffset(player, world, state, pos, ray)
.placeInWorld(world, this, player, context.getHand(), ray);
}
if (integratedCogHelperId != -1) {
helper = PlacementHelpers.get(integratedCogHelperId);
if (helper.matchesState(state) && player != null && !player.isShiftKeyDown()) {
return helper.getOffset(player, world, state, pos, ray)
.placeInWorld(world, this, player, context.getHand(), ray);
}
}
return super.onItemUseFirst(stack, context);
}
@MethodsReturnNonnullByDefault
private static class SmallCogHelper extends DiagonalCogHelper {
@Override
public Predicate<ItemStack> getItemPredicate() {
return ((Predicate<ItemStack>) ICogWheel::isSmallCogItem).and(ICogWheel::isDedicatedCogItem);
}
@Override
public PlacementOffset getOffset(Player player, Level world, BlockState state, BlockPos pos,
BlockHitResult ray) {
if (hitOnShaft(state, ray))
return PlacementOffset.fail();
if (!ICogWheel.isLargeCog(state)) {
Axis axis = ((IRotate) state.getBlock()).getRotationAxis(state);
List<Direction> directions = IPlacementHelper.orderedByDistanceExceptAxis(pos, ray.getLocation(), axis);
for (Direction dir : directions) {
BlockPos newPos = pos.relative(dir);
if (!TFMGCogWheelBlock.isValidCogwheelPosition(false, world, newPos, axis))
continue;
if (!world.getBlockState(newPos)
.getMaterial()
.isReplaceable())
continue;
return PlacementOffset.success(newPos, s -> s.setValue(AXIS, axis));
}
return PlacementOffset.fail();
}
return super.getOffset(player, world, state, pos, ray);
}
}
@MethodsReturnNonnullByDefault
private static class LargeCogHelper extends DiagonalCogHelper {
@Override
public Predicate<ItemStack> getItemPredicate() {
return ((Predicate<ItemStack>) ICogWheel::isLargeCogItem).and(ICogWheel::isDedicatedCogItem);
}
@Override
public PlacementOffset getOffset(Player player, Level world, BlockState state, BlockPos pos,
BlockHitResult ray) {
if (hitOnShaft(state, ray))
return PlacementOffset.fail();
if (ICogWheel.isLargeCog(state)) {
Axis axis = ((IRotate) state.getBlock()).getRotationAxis(state);
Direction side = IPlacementHelper.orderedByDistanceOnlyAxis(pos, ray.getLocation(), axis)
.get(0);
List<Direction> directions = IPlacementHelper.orderedByDistanceExceptAxis(pos, ray.getLocation(), axis);
for (Direction dir : directions) {
BlockPos newPos = pos.relative(dir)
.relative(side);
if (!TFMGCogWheelBlock.isValidCogwheelPosition(true, world, newPos, dir.getAxis()))
continue;
if (!world.getBlockState(newPos)
.getMaterial()
.isReplaceable())
continue;
return PlacementOffset.success(newPos, s -> s.setValue(AXIS, dir.getAxis()));
}
return PlacementOffset.fail();
}
return super.getOffset(player, world, state, pos, ray);
}
}
@MethodsReturnNonnullByDefault
public abstract static class DiagonalCogHelper implements IPlacementHelper {
@Override
public Predicate<BlockState> getStatePredicate() {
return s -> ICogWheel.isSmallCog(s) || ICogWheel.isLargeCog(s);
}
@Override
public PlacementOffset getOffset(Player player, Level world, BlockState state, BlockPos pos,
BlockHitResult ray) {
// diagonal gears of different size
Axis axis = ((IRotate) state.getBlock()).getRotationAxis(state);
Direction closest = IPlacementHelper.orderedByDistanceExceptAxis(pos, ray.getLocation(), axis)
.get(0);
List<Direction> directions = IPlacementHelper.orderedByDistanceExceptAxis(pos, ray.getLocation(), axis,
d -> d.getAxis() != closest.getAxis());
for (Direction dir : directions) {
BlockPos newPos = pos.relative(dir)
.relative(closest);
if (!world.getBlockState(newPos)
.getMaterial()
.isReplaceable())
continue;
if (!TFMGCogWheelBlock.isValidCogwheelPosition(ICogWheel.isLargeCog(state), world, newPos, axis))
continue;
return PlacementOffset.success(newPos, s -> s.setValue(AXIS, axis));
}
return PlacementOffset.fail();
}
protected boolean hitOnShaft(BlockState state, BlockHitResult ray) {
return AllShapes.SIX_VOXEL_POLE.get(((IRotate) state.getBlock()).getRotationAxis(state))
.bounds()
.inflate(0.001)
.contains(ray.getLocation()
.subtract(ray.getLocation()
.align(Iterate.axisSet)));
}
}
@MethodsReturnNonnullByDefault
public static class IntegratedLargeCogHelper implements IPlacementHelper {
@Override
public Predicate<ItemStack> getItemPredicate() {
return ((Predicate<ItemStack>) ICogWheel::isLargeCogItem).and(ICogWheel::isDedicatedCogItem);
}
@Override
public Predicate<BlockState> getStatePredicate() {
return s -> !ICogWheel.isDedicatedCogWheel(s.getBlock()) && ICogWheel.isSmallCog(s);
}
@Override
public PlacementOffset getOffset(Player player, Level world, BlockState state, BlockPos pos,
BlockHitResult ray) {
Direction face = ray.getDirection();
Axis newAxis;
if (state.hasProperty(HorizontalKineticBlock.HORIZONTAL_FACING))
newAxis = state.getValue(HorizontalKineticBlock.HORIZONTAL_FACING)
.getAxis();
else if (state.hasProperty(DirectionalKineticBlock.FACING))
newAxis = state.getValue(DirectionalKineticBlock.FACING)
.getAxis();
else if (state.hasProperty(RotatedPillarKineticBlock.AXIS))
newAxis = state.getValue(RotatedPillarKineticBlock.AXIS);
else
newAxis = Axis.Y;
if (face.getAxis() == newAxis)
return PlacementOffset.fail();
List<Direction> directions =
IPlacementHelper.orderedByDistanceExceptAxis(pos, ray.getLocation(), face.getAxis(), newAxis);
for (Direction d : directions) {
BlockPos newPos = pos.relative(face)
.relative(d);
if (!world.getBlockState(newPos)
.getMaterial()
.isReplaceable())
continue;
if (!TFMGCogWheelBlock.isValidCogwheelPosition(false, world, newPos, newAxis))
return PlacementOffset.fail();
return PlacementOffset.success(newPos, s -> s.setValue(TFMGCogWheelBlock.AXIS, newAxis));
}
return PlacementOffset.fail();
}
}
@MethodsReturnNonnullByDefault
public static class IntegratedSmallCogHelper implements IPlacementHelper {
@Override
public Predicate<ItemStack> getItemPredicate() {
return ((Predicate<ItemStack>) ICogWheel::isSmallCogItem).and(ICogWheel::isDedicatedCogItem);
}
@Override
public Predicate<BlockState> getStatePredicate() {
return s -> !ICogWheel.isDedicatedCogWheel(s.getBlock()) && ICogWheel.isSmallCog(s);
}
@Override
public PlacementOffset getOffset(Player player, Level world, BlockState state, BlockPos pos,
BlockHitResult ray) {
Direction face = ray.getDirection();
Axis newAxis;
if (state.hasProperty(HorizontalKineticBlock.HORIZONTAL_FACING))
newAxis = state.getValue(HorizontalKineticBlock.HORIZONTAL_FACING)
.getAxis();
else if (state.hasProperty(DirectionalKineticBlock.FACING))
newAxis = state.getValue(DirectionalKineticBlock.FACING)
.getAxis();
else if (state.hasProperty(RotatedPillarKineticBlock.AXIS))
newAxis = state.getValue(RotatedPillarKineticBlock.AXIS);
else
newAxis = Axis.Y;
if (face.getAxis() == newAxis)
return PlacementOffset.fail();
List<Direction> directions = IPlacementHelper.orderedByDistanceExceptAxis(pos, ray.getLocation(), newAxis);
for (Direction d : directions) {
BlockPos newPos = pos.relative(d);
if (!world.getBlockState(newPos)
.getMaterial()
.isReplaceable())
continue;
if (!TFMGCogWheelBlock.isValidCogwheelPosition(false, world, newPos, newAxis))
return PlacementOffset.fail();
return PlacementOffset.success()
.at(newPos)
.withTransform(s -> s.setValue(TFMGCogWheelBlock.AXIS, newAxis));
}
return PlacementOffset.fail();
}
}
}

View File

@@ -0,0 +1,117 @@
package com.drmangotea.createindustry.blocks.cogwheeels;
import com.drmangotea.createindustry.registry.TFMGBlocks;
import com.drmangotea.createindustry.registry.TFMGPartialModels;
import com.jozufozu.flywheel.api.Instancer;
import com.jozufozu.flywheel.api.Material;
import com.jozufozu.flywheel.api.MaterialManager;
import com.jozufozu.flywheel.core.PartialModel;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Vector3f;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.kinetics.base.KineticBlockEntityRenderer;
import com.simibubi.create.content.kinetics.base.SingleRotatingInstance;
import com.simibubi.create.content.kinetics.base.flwdata.RotatingData;
import com.simibubi.create.content.kinetics.simpleRelays.BracketedKineticBlockEntity;
import com.simibubi.create.content.kinetics.simpleRelays.BracketedKineticBlockEntityRenderer;
import com.simibubi.create.content.kinetics.simpleRelays.ICogWheel;
import com.simibubi.create.content.kinetics.simpleRelays.SimpleKineticBlockEntity;
import com.simibubi.create.foundation.render.AllMaterialSpecs;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Direction.Axis;
import net.minecraft.core.Direction.AxisDirection;
public class TFMGCogwheelInstance extends SingleRotatingInstance<SimpleKineticBlockEntity> {
protected RotatingData additionalShaft;
public TFMGCogwheelInstance(MaterialManager materialManager, SimpleKineticBlockEntity blockEntity) {
super(materialManager, blockEntity);
}
@Override
public void init() {
super.init();
if (!ICogWheel.isLargeCog(blockEntity.getBlockState()))
return;
// Large cogs sometimes have to offset their teeth by 11.25 degrees in order to
// mesh properly
float speed = blockEntity.getSpeed();
Axis axis = KineticBlockEntityRenderer.getRotationAxisOf(blockEntity);
BlockPos pos = blockEntity.getBlockPos();
float offset = BracketedKineticBlockEntityRenderer.getShaftAngleOffset(axis, pos);
Direction facing = Direction.fromAxisAndDirection(axis, AxisDirection.POSITIVE);
Instancer<RotatingData> half = getRotatingMaterial().getModel(AllPartialModels.COGWHEEL_SHAFT, blockState,
facing, () -> this.rotateToAxis(axis));
additionalShaft = setup(half.createInstance(), speed);
additionalShaft.setRotationOffset(offset);
}
@Override
protected Instancer<RotatingData> getModel() {
Axis axis = KineticBlockEntityRenderer.getRotationAxisOf(blockEntity);
Direction facing = Direction.fromAxisAndDirection(axis, AxisDirection.POSITIVE);
if (!ICogWheel.isLargeCog(blockEntity.getBlockState()))
return getCutoutRotatingMaterial().getModel(blockState);
//return super.getModel();
PartialModel model = blockEntity.getBlockState().is(TFMGBlocks.LARGE_ALUMINUM_COGWHEEL.get()) ? TFMGPartialModels.LARGE_ALUMINUM_COGHWEEL : TFMGPartialModels.LARGE_STEEL_COGHWEEL;
return getCutoutRotatingMaterial().getModel(model, blockState, facing,
() -> this.rotateToAxis(axis));
}
protected Material<RotatingData> getCutoutRotatingMaterial() {
return materialManager.defaultCutout()
.material(AllMaterialSpecs.ROTATING);
}
private PoseStack rotateToAxis(Axis axis) {
Direction facing = Direction.fromAxisAndDirection(axis, AxisDirection.POSITIVE);
PoseStack poseStack = new PoseStack();
TransformStack.cast(poseStack)
.centre()
.rotateToFace(facing)
.multiply(Vector3f.XN.rotationDegrees(-90))
.unCentre();
return poseStack;
}
@Override
public void update() {
super.update();
if (additionalShaft != null) {
updateRotation(additionalShaft);
additionalShaft.setRotationOffset(TFMGCogwheelRenderer.getShaftAngleOffset(axis, pos));
}
}
@Override
public void updateLight() {
super.updateLight();
if (additionalShaft != null)
relight(pos, additionalShaft);
}
@Override
public void remove() {
super.remove();
if (additionalShaft != null)
additionalShaft.delete();
}
}

View File

@@ -0,0 +1,79 @@
package com.drmangotea.createindustry.blocks.cogwheeels;
import com.drmangotea.createindustry.registry.TFMGBlocks;
import com.drmangotea.createindustry.registry.TFMGPartialModels;
import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.core.PartialModel;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.kinetics.base.KineticBlockEntityRenderer;
import com.simibubi.create.content.kinetics.simpleRelays.BracketedKineticBlockEntity;
import com.simibubi.create.content.kinetics.simpleRelays.SimpleKineticBlockEntity;
import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider.Context;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Direction.Axis;
import net.minecraft.core.Direction.AxisDirection;
public class TFMGCogwheelRenderer extends KineticBlockEntityRenderer<SimpleKineticBlockEntity> {
public TFMGCogwheelRenderer(Context context) {
super(context);
}
@Override
protected void renderSafe(SimpleKineticBlockEntity be, float partialTicks, PoseStack ms,
MultiBufferSource buffer, int light, int overlay) {
if (Backend.canUseInstancing(be.getLevel()))
return;
if (!AllBlocks.LARGE_COGWHEEL.has(be.getBlockState())) {
super.renderSafe(be, partialTicks, ms, buffer, light, overlay);
return;
}
Axis axis = getRotationAxisOf(be);
Direction facing = Direction.fromAxisAndDirection(axis, AxisDirection.POSITIVE);
PartialModel model = be.getBlockState().is(TFMGBlocks.LARGE_ALUMINUM_COGWHEEL.get()) ? TFMGPartialModels.LARGE_ALUMINUM_COGHWEEL : TFMGPartialModels.LARGE_STEEL_COGHWEEL;
renderRotatingBuffer(be,
CachedBufferer.partialFacingVertical(model, be.getBlockState(), facing),
ms, buffer.getBuffer(RenderType.cutoutMipped()), light);
float angle = getAngleForLargeCogShaft(be, axis);
SuperByteBuffer shaft =
CachedBufferer.partialFacingVertical(AllPartialModels.COGWHEEL_SHAFT, be.getBlockState(), facing);
kineticRotationTransform(shaft, be, axis, angle, light);
shaft.renderInto(ms, buffer.getBuffer(RenderType.solid()));
}
public static float getAngleForLargeCogShaft(SimpleKineticBlockEntity be, Axis axis) {
BlockPos pos = be.getBlockPos();
float offset = getShaftAngleOffset(axis, pos);
float time = AnimationTickHolder.getRenderTime(be.getLevel());
float angle = ((time * be.getSpeed() * 3f / 10 + offset) % 360) / 180 * (float) Math.PI;
return angle;
}
public static float getShaftAngleOffset(Axis axis, BlockPos pos) {
float offset = 0;
double d = (((axis == Axis.X) ? 0 : pos.getX()) + ((axis == Axis.Y) ? 0 : pos.getY())
+ ((axis == Axis.Z) ? 0 : pos.getZ())) % 2;
if (d == 0)
offset = 22.5f;
return offset;
}
}

View File

@@ -0,0 +1,100 @@
package com.drmangotea.createindustry.blocks.decoration;
import com.drmangotea.createindustry.blocks.electricity.base.WallMountBlock;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.util.RandomSource;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.SimpleWaterloggedBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.material.Fluids;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
import java.util.Map;
public class LithiumTorchBlock extends WallMountBlock implements SimpleWaterloggedBlock {
public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED;
private static final Map<Direction, VoxelShape> SHAPE = Maps.newEnumMap(ImmutableMap.of(Direction.NORTH, Block.box(5.5D, 3.0D, 11.0D, 10.5D, 13.0D, 16.0D), Direction.SOUTH, Block.box(5.5D, 3.0D, 0.0D, 10.5D, 13.0D, 5.0D), Direction.WEST, Block.box(11.0D, 3.0D, 5.5D, 16.0D, 13.0D, 10.5D), Direction.EAST, Block.box(0.0D, 3.0D, 5.5D, 5.0D, 13.0D, 10.5D),Direction.UP,Block.box(6.0D, 0.0D, 6.0D, 10.0D, 10.0D, 10.0D),Direction.DOWN,Block.box(6.0D, 6.0D, 6.0D, 10.0D, 16.0D, 10.0D)));
public LithiumTorchBlock(Properties pProperties) {
super(pProperties);
}
public VoxelShape getShape(BlockState pState, BlockGetter pLevel, BlockPos pPos, CollisionContext pContext) {
return SHAPE.get(pState.getValue(FACING));
}
@Override
public FluidState getFluidState(BlockState p_51475_) {
return p_51475_.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(p_51475_);
}
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> p_55125_) {
p_55125_.add(WATERLOGGED,FACING);
}
public void animateTick(BlockState pState, Level pLevel, BlockPos pPos, RandomSource pRandom) {
Direction direction = pState.getValue(FACING);
double d0 = (double)pPos.getX() + 0.5D;
double d1 = (double)pPos.getY() + 0.7D;
double d2 = (double)pPos.getZ() + 0.5D;
double d3 = 0.22D;
double d4 = 0.27D;
Direction direction1 = direction.getOpposite();
double y;
if(direction == Direction.DOWN) {
y = d1 - 0.22D * (double) direction1.getStepY();
}else {
y = d1 + 0.11D;
}
pLevel.addParticle(ParticleTypes.SMOKE, d0 + 0.27D * (double)direction1.getStepX(), y, d2 + 0.27D * (double)direction1.getStepZ(), 0.0D, 0.0D, 0.0D);
pLevel.addParticle(ParticleTypes.FLAME, d0 + 0.27D * (double)direction1.getStepX(), y, d2 + 0.27D * (double)direction1.getStepZ(), 0.0D, 0.0D, 0.0D);
}
public BlockState updateShape(BlockState pState, Direction pFacing, BlockState pFacingState, LevelAccessor pLevel, BlockPos pCurrentPos, BlockPos pFacingPos) {
if (pState.getValue(WATERLOGGED)) {
pLevel.scheduleTick(pCurrentPos, Fluids.WATER, Fluids.WATER.getTickDelay(pLevel));
}
return !this.canSurvive(pState, pLevel, pCurrentPos) ? Blocks.AIR.defaultBlockState() : pState;
}
public boolean canSurvive(BlockState pState, LevelReader pLevel, BlockPos pPos) {
Direction direction = pState.getValue(FACING);
BlockPos blockpos = pPos.relative(direction.getOpposite());
BlockState blockstate = pLevel.getBlockState(blockpos);
return blockstate.isFaceSturdy(pLevel, blockpos, direction);
}
public BlockState getStateForPlacement(BlockPlaceContext pContext) {
FluidState fluidstate = pContext.getLevel().getFluidState(pContext.getClickedPos());
boolean flag = fluidstate.getType() == Fluids.WATER;
return this.defaultBlockState().setValue(FACING, pContext.getClickedFace()).setValue(WATERLOGGED,flag);
}
}

View File

@@ -0,0 +1,43 @@
package com.drmangotea.createindustry.blocks.decoration;
import com.drmangotea.createindustry.blocks.electricity.cable_blocks.DiagonalCableBlock;
import com.simibubi.create.foundation.data.SpecialBlockStateGen;
import com.tterrag.registrate.providers.DataGenContext;
import com.tterrag.registrate.providers.RegistrateBlockstateProvider;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.client.model.generators.ModelFile;
import static com.drmangotea.createindustry.blocks.electricity.base.WallMountBlock.FACING;
import static com.simibubi.create.foundation.data.AssetLookup.partialBaseModel;
public class LithiumTorchGenerator extends SpecialBlockStateGen {
@Override
protected int getXRotation(BlockState state) {
return state.getValue(FACING)== Direction.DOWN ? 180 : 0;
}
@Override
protected int getYRotation(BlockState state) {
return switch (state.getValue(FACING)) {
case NORTH -> 270;
case SOUTH -> 90;
case WEST -> 180;
case EAST -> 0;
case DOWN -> 0;
case UP -> 0;
};
}
@Override
public <T extends Block> ModelFile getModel(DataGenContext<Block, T> ctx, RegistrateBlockstateProvider prov,
BlockState state) {
return state.getValue(FACING).getAxis().isHorizontal() ? partialBaseModel(ctx, prov, "wall")
: partialBaseModel(ctx, prov);
}
}

View File

@@ -0,0 +1,88 @@
package com.drmangotea.createindustry.blocks.decoration.kinetics;
import com.drmangotea.createindustry.registry.TFMGBlockEntities;
import com.drmangotea.createindustry.registry.TFMGItems;
import com.simibubi.create.AllBlockEntityTypes;
import com.simibubi.create.AllItems;
import com.simibubi.create.content.kinetics.base.RotatedPillarKineticBlock;
import com.simibubi.create.content.kinetics.gearbox.GearboxBlockEntity;
import com.simibubi.create.foundation.block.IBE;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Direction.Axis;
import net.minecraft.core.NonNullList;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.PushReaction;
import net.minecraft.world.level.storage.loot.LootContext.Builder;
import net.minecraft.world.phys.HitResult;
import java.util.Arrays;
import java.util.List;
public class SteelGearboxBlock extends RotatedPillarKineticBlock implements IBE<GearboxBlockEntity> {
public SteelGearboxBlock(Properties properties) {
super(properties);
}
@Override
public PushReaction getPistonPushReaction(BlockState state) {
return PushReaction.PUSH_ONLY;
}
@Override
public void fillItemCategory(CreativeModeTab group, NonNullList<ItemStack> items) {
super.fillItemCategory(group, items);
items.add(TFMGItems.STEEL_VERTICAL_GEARBOX.asStack());
}
@SuppressWarnings("deprecation")
@Override
public List<ItemStack> getDrops(BlockState state, Builder builder) {
if (state.getValue(AXIS).isVertical())
return super.getDrops(state, builder);
return Arrays.asList(new ItemStack(TFMGItems.STEEL_VERTICAL_GEARBOX.get()));
}
@Override
public ItemStack getCloneItemStack(BlockState state, HitResult target, BlockGetter world, BlockPos pos,
Player player) {
if (state.getValue(AXIS).isVertical())
return super.getCloneItemStack(state, target, world, pos, player);
return new ItemStack(TFMGItems.STEEL_VERTICAL_GEARBOX.get());
}
@Override
public BlockState getStateForPlacement(BlockPlaceContext context) {
return defaultBlockState().setValue(AXIS, Axis.Y);
}
// IRotate:
@Override
public boolean hasShaftTowards(LevelReader world, BlockPos pos, BlockState state, Direction face) {
return face.getAxis() != state.getValue(AXIS);
}
@Override
public Axis getRotationAxis(BlockState state) {
return state.getValue(AXIS);
}
@Override
public Class<GearboxBlockEntity> getBlockEntityClass() {
return GearboxBlockEntity.class;
}
@Override
public BlockEntityType<? extends GearboxBlockEntity> getBlockEntityType() {
return TFMGBlockEntities.STEEL_GEARBOX.get();
}
}

View File

@@ -0,0 +1,68 @@
package com.drmangotea.createindustry.blocks.decoration.kinetics;
import com.drmangotea.createindustry.registry.TFMGBlocks;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.content.kinetics.base.IRotate;
import com.simibubi.create.foundation.utility.Iterate;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Direction.Axis;
import net.minecraft.core.NonNullList;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import java.util.Map;
public class SteelVerticalGearboxItem extends BlockItem {
public SteelVerticalGearboxItem(Properties builder) {
super(TFMGBlocks.STEEL_GEARBOX.get(), builder);
}
@Override
public String getDescriptionId() {
return "item.createindustry.steel_vertical_gearbox";
}
@Override
public void fillItemCategory(CreativeModeTab p_150895_1_, NonNullList<ItemStack> p_150895_2_) {
}
@Override
public void registerBlocks(Map<Block, Item> p_195946_1_, Item p_195946_2_) {
}
@Override
protected boolean updateCustomBlockEntityTag(BlockPos pos, Level world, Player player, ItemStack stack, BlockState state) {
Axis prefferedAxis = null;
for (Direction side : Iterate.horizontalDirections) {
BlockState blockState = world.getBlockState(pos.relative(side));
if (blockState.getBlock() instanceof IRotate) {
if (((IRotate) blockState.getBlock()).hasShaftTowards(world, pos.relative(side), blockState,
side.getOpposite()))
if (prefferedAxis != null && prefferedAxis != side.getAxis()) {
prefferedAxis = null;
break;
} else {
prefferedAxis = side.getAxis();
}
}
}
Axis axis = prefferedAxis == null ? player.getDirection()
.getClockWise()
.getAxis() : prefferedAxis == Axis.X ? Axis.Z : Axis.X;
world.setBlockAndUpdate(pos, state.setValue(BlockStateProperties.AXIS, axis));
return super.updateCustomBlockEntityTag(pos, world, player, stack, state);
}
}

View File

@@ -0,0 +1,40 @@
package com.drmangotea.createindustry.blocks.electricity.base;
import com.drmangotea.createindustry.registry.TFMGBlockEntities;
import com.simibubi.create.content.equipment.wrench.IWrenchable;
import com.simibubi.create.foundation.block.IBE;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
public class ConverterBlock extends Block implements IBE<ConverterBlockEntity>, IWrenchable {
public ConverterBlock(Properties p_49795_) {
super(p_49795_);
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
super.createBlockStateDefinition(builder);
}
@Override
public Class<ConverterBlockEntity> getBlockEntityClass() {
return ConverterBlockEntity.class;
}
@Override
public BlockEntityType<? extends ConverterBlockEntity> getBlockEntityType() {
return TFMGBlockEntities.CONVERTER.get();
}
}

View File

@@ -0,0 +1,123 @@
package com.drmangotea.createindustry.blocks.electricity.base;
import com.drmangotea.createindustry.CreateTFMG;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import java.util.List;
public class ConverterBlockEntity extends ElectricBlockEntity {
public int lastVoltage=0;
public ConverterBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
}
@Override
public boolean addToGoggleTooltip(List<Component> tooltip, boolean isPlayerSneaking) {
return false;
}
@Override
public void tick() {
super.tick();
}
@Override
public float maxVoltage() {
return 1000;
}
//@Override
// public void manageVoltage(){
//
// if(voltageGeneration()>0) {
// voltage = voltageGeneration();
// distanceFromSource = 0;
// }
//
//
//
// current = energy.getEnergyStored()/(voltage+1);
//
// if(voltage == 0)
// setDistanceFromSource(Integer.MAX_VALUE);
//
//
//
// if(voltage>maxVoltage()){
// explode();
// voltage = 0;
// }
//
//
//
// }
@Override
public int voltageGeneration() {
if(energy.getEnergyStored()==0) {
return 0;
}
return 255;
}
@Override
public int FECapacity() {
return 10000;
}
@Override
public int transferSpeed() {
return 1000;
}
//@Override
//public boolean isStorage() {
// return true;
//}
@Override
public boolean hasElectricitySlot(Direction direction) {
return direction.getAxis().isVertical();
}
//@Override
//public void write(CompoundTag compound, boolean clientPacket) {
// super.write(compound, clientPacket);
//
// compound.putInt("LastVoltage",lastVoltage);
//}
//
//@Override
//protected void read(CompoundTag compound, boolean clientPacket) {
// super.read(compound, clientPacket);
//
// lastVoltage = compound.getInt("LastVoltage");
//
//}
}

View File

@@ -0,0 +1,314 @@
package com.drmangotea.createindustry.blocks.electricity.base;
import com.drmangotea.createindustry.base.util.TFMGUtils;
import com.simibubi.create.content.equipment.goggles.IHaveGoggleInformation;
import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
import com.simibubi.create.foundation.utility.Lang;
import net.minecraft.ChatFormatting;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ForgeCapabilities;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.energy.IEnergyStorage;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
import java.util.List;
public class ElectricBlockEntity extends SmartBlockEntity implements IHaveGoggleInformation, IElectricBlock {
public int voltage=0;
public int current =0;
private boolean gotFElastTick = false;
public int distanceFromSource = Integer.MAX_VALUE;
private LazyOptional<IEnergyStorage> lazyEnergyHandler = LazyOptional.empty();
public final TFMGForgeEnergyStorage energy = createEnergyStorage();
public ElectricBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
}
public void tick(){
super.tick();
energy.receiveEnergy(feGeneration(),false);
manageVoltage();
sendCharge(level,getBlockPos());
}
public TFMGForgeEnergyStorage getEnergy() {
return energy;
}
@Override
public void onLoad() {
super.onLoad();
lazyEnergyHandler = LazyOptional.of(() -> energy);
}
@Override
public void invalidateCaps() {
super.invalidateCaps();
lazyEnergyHandler.invalidate();
}
@Override
public @NotNull <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap, @Nullable Direction side) {
if (cap == ForgeCapabilities.ENERGY&&side == null) {
return lazyEnergyHandler.cast();
} else
if (cap == ForgeCapabilities.ENERGY&&hasElectricitySlot(side)) {
return lazyEnergyHandler.cast();
}
return super.getCapability(cap, side);
}
public void manageVoltage(){
if(voltageGeneration()>0) {
voltage = voltageGeneration();
distanceFromSource = 0;
}
if(distanceFromSource == Integer.MAX_VALUE)
voltage = 0;
current = energy.getEnergyStored()/(voltage+1);
if(voltage>maxVoltage()){
voltage = 0;
explode();
voltage = 0;
}
}
@Override
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
}
@Override
@SuppressWarnings("removal")
public boolean addToGoggleTooltip(List<Component> tooltip, boolean isPlayerSneaking) {
//if(energy.getEnergyStored()==0&&voltageGeneration()==0)
// Lang.translate("goggles.electric_machine.no_power")
// .style(ChatFormatting.RED)
// .forGoggles(tooltip, 1);
//
//
//Lang.translate("goggles.blast_furnace.height", voltage)
// .style(ChatFormatting.DARK_PURPLE)
// .forGoggles(tooltip, 1);
//
//Lang.translate("goggles.blast_furnace.height", current)
// .style(ChatFormatting.LIGHT_PURPLE)
// .forGoggles(tooltip, 1);
//
//Lang.translate("goggles.blast_furnace.height", energy.getEnergyStored())
// .style(ChatFormatting.DARK_RED)
// .forGoggles(tooltip, 1);
//
//Lang.translate("goggles.blast_furnace.height", distanceFromSource)
// .style(ChatFormatting.DARK_AQUA)
// .forGoggles(tooltip, 1);
return true;
}
@Override
public float internalResistance() {
return 0;
}
@Override
public int getVoltage() {
return voltage;
}
@Override
public boolean gotFElastTick(int value) {
gotFElastTick = value == 3 ? gotFElastTick : value == 1;
return gotFElastTick;
}
@Override
public int getCurrent() {
return current;
}
@Override
public void addVoltage(float amount) {
// if(voltageGeneration()>0)
// return;
voltage = (int) amount;
//voltage = (int) ((getVoltage()+amount)/2);
}
public void addVoltageFromNonTFMGBlock() {
//if(voltage<250) {
// voltage = 250;
//
//}
}
@Override
public TFMGForgeEnergyStorage getForgeEnergy() {
return energy;
}
@Override
public boolean hasElectricitySlot(Direction direction) {
return false;
}
@Override
public float maxVoltage() {
return 500;
}
@Override
public void explode() {
TFMGUtils.createFireExplosion(level,null, getBlockPos(),10,1.5f);
}
@Override
public int FECapacity() {
return 10000;
}
@Override
public int getDistanceFromSource() {
return distanceFromSource;
}
@Override
public void setDistanceFromSource(int value) {
distanceFromSource = value;
// sendStuff();
}
@Override
public void sendStuff() {
sendData();
setChanged();
}
@Override
public void write(CompoundTag compound, boolean clientPacket) {
super.write(compound, clientPacket);
writeElectrity(compound);
;
}
@Override
protected void read(CompoundTag compound, boolean clientPacket) {
super.read(compound, clientPacket);
voltage = compound.getInt("Voltage");
current = compound.getInt("Current");
distanceFromSource = compound.getInt("DistanceFromSource");
energy.setEnergy(compound.getInt("ForgeEnergy"));
}
@Override
public int feGeneration() {
return 0;
}
@Override
public int voltageGeneration() {
return 0;
}
@Override
public int transferSpeed() {
return 3000;
}
}

View File

@@ -0,0 +1,332 @@
package com.drmangotea.createindustry.blocks.electricity.base;
import com.drmangotea.createindustry.CreateTFMG;
import com.drmangotea.createindustry.blocks.electricity.capacitor.CapacitorBlockEntity;
import com.drmangotea.createindustry.blocks.electricity.resistors.ResistorBlockEntity;
import com.drmangotea.createindustry.registry.TFMGBlocks;
import com.simibubi.create.Create;
import com.simibubi.create.foundation.utility.Iterate;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.LeverBlock;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.common.capabilities.ForgeCapabilities;
import net.minecraftforge.energy.EnergyStorage;
public interface IElectricBlock {
float internalResistance();
int getVoltage();
boolean gotFElastTick(int value);
int getCurrent();
int feGeneration();
int voltageGeneration();
int transferSpeed();
void addVoltage(float amount);
default float getCharge(){
return getCurrent()*getVoltage();
}
default boolean isStorage(){
return false;
}
TFMGForgeEnergyStorage getForgeEnergy();
boolean hasElectricitySlot(Direction direction);
float maxVoltage();
void explode();
int FECapacity();
int getDistanceFromSource();
void setDistanceFromSource(int value);
void sendStuff();
default boolean canBeDisabled(){
return false;
}
default boolean hasSignal() {
return false;
}
default void sendCharge(Level level, BlockPos pos){
int lowestDistance = Integer.MAX_VALUE;
boolean getsVoltageFromNonTFMGBlock = false;
if(canBeDisabled()){
if(hasSignal()) {
setDistanceFromSource(Integer.MAX_VALUE);
return;
}
}
for(Direction direction : Direction.values()){
if(hasElectricitySlot(direction)){
BlockEntity be1 =level.getBlockEntity(pos.relative(direction));
if(be1 instanceof IElectricBlock be2){
if(be2.hasElectricitySlot(direction.getOpposite())) {
int distance = be2.getDistanceFromSource();
if(!isStorage()&&be2.isStorage()&&direction == Direction.UP)
distance = Integer.MAX_VALUE;
if(getVoltage()==0) {
if(distance>getDistanceFromSource())
be2.addVoltage(getVoltage());
}
if(!(be2 instanceof ConverterBlockEntity))
if(!(isStorage()&&direction == Direction.DOWN))
if(!(!isStorage()&&be2.isStorage()&&direction == Direction.DOWN))
if(getVoltage()!=0) {
// if(Create.RANDOM.nextInt(3) ==1)
transferCharge(be2);
if(distance>getDistanceFromSource()){
be2.addVoltage(getVoltage());
}
}
lowestDistance = Math.min(lowestDistance,distance);
}
if(direction.getAxis().isHorizontal()) {
if (be2 instanceof ResistorBlockEntity resistorBE)
if (resistorBE.hasElectricitySlot(direction) && resistorBE.getVoltageOutput() > 0) {
lowestDistance = 0;
addVoltage(resistorBE.getVoltageOutput());
}
}
}else
if(be1!=null) {
if (be1.getCapability(ForgeCapabilities.ENERGY, direction.getOpposite()).isPresent() && getForgeEnergy().getEnergyStored() > 0) {
if (!(be1.getCapability(ForgeCapabilities.ENERGY).orElse(new EnergyStorage(0)) instanceof TFMGForgeEnergyStorage)
&& be1.getCapability(ForgeCapabilities.ENERGY).orElse(new EnergyStorage(0)).getEnergyStored() > 0 &&
be1.getCapability(ForgeCapabilities.ENERGY, direction.getOpposite()).orElse(new EnergyStorage(0)).canReceive()
) {
// lowestDistance = 0;
// setDistanceFromSource(1);
// getsVoltageFromNonTFMGBlock = true;
}
}
}
}
}
if (lowestDistance != Integer.MAX_VALUE&&voltageGeneration()==0) {
if( lowestDistance >= getDistanceFromSource()){
}else {
if(Create.RANDOM.nextInt(2)==0)
setDistanceFromSource(lowestDistance + 1);
}
// sendStuff();
}
//else distanceFromSource = Integer.MAX_VALUE;
if(voltageGeneration()>0){
setDistanceFromSource(0);
// sendStuff();
}
if(!level.isClientSide)
if(lowestDistance == getDistanceFromSource()+1&&this.voltageGeneration()==0&&!getsVoltageFromNonTFMGBlock){
setDistanceFromSource(Integer.MAX_VALUE);
// sendStuff();
}
if(!level.isClientSide)
if(getDistanceFromSource()<lowestDistance&&getDistanceFromSource() >0&&this.voltageGeneration()==0&&!getsVoltageFromNonTFMGBlock){
setDistanceFromSource(Integer.MAX_VALUE);
// sendStuff();
//
}
if(!level.isClientSide)
if(lowestDistance == Integer.MAX_VALUE && voltageGeneration() == 0&&!getsVoltageFromNonTFMGBlock){
setDistanceFromSource(Integer.MAX_VALUE);
// sendStuff();
}
//if(voltageGeneration()>0)
// setDistanceFromSource(0);
if(lowestDistance>=getDistanceFromSource()&&getDistanceFromSource()!=0)
setDistanceFromSource(Integer.MAX_VALUE);
if(getDistanceFromSource()==Integer.MAX_VALUE)
addVoltage(0);
}
default void transferCharge(IElectricBlock be) {
if(!isStorage()) {
if (be.getDistanceFromSource() > getDistanceFromSource()||be.isStorage()) {
//int amount = getForgeEnergy().extractEnergy(transferSpeed(), true);
//int amount2 = be.getForgeEnergy().receiveEnergy( transferSpeed(), true);
int amount = getForgeEnergy().extractEnergy(transferSpeed()*100, true);
int amount2 = be.getForgeEnergy().receiveEnergy(transferSpeed()*100, true);
getForgeEnergy().extractEnergy(Math.min(amount, amount2), false);
be.getForgeEnergy().receiveEnergy(Math.min(amount, amount2), false);
}
if(be.getDistanceFromSource()==getDistanceFromSource()&&getForgeEnergy().getEnergyStored()>be.getForgeEnergy().getEnergyStored()){
int diff = Math.abs(getForgeEnergy().getEnergyStored()-be.getForgeEnergy().getEnergyStored());
int amount = getForgeEnergy().extractEnergy(diff / 2, true);
int amount2 = be.getForgeEnergy().receiveEnergy( diff / 2, true);
getForgeEnergy().extractEnergy( Math.min(amount,amount2), false);
be.getForgeEnergy().receiveEnergy( Math.min(amount,amount2), false);
}
}
if(isStorage()){
if(be.isStorage()){
if(!be.isStorage()||(be.isStorage()&&be.getForgeEnergy().getEnergyStored()<getForgeEnergy().getEnergyStored())) {
// if(be.getDistanceFromSource()>=getDistanceFromSource()) {
int amount = getForgeEnergy().extractEnergy(transferSpeed()*10, true);
int amount2 = be.getForgeEnergy().receiveEnergy(transferSpeed()*10, true);
getForgeEnergy().extractEnergy(Math.min(amount, amount2), false);
be.getForgeEnergy().receiveEnergy(Math.min(amount, amount2), false);
}
}else {
int amount = getForgeEnergy().extractEnergy(transferSpeed(), true);
int amount2 = be.getForgeEnergy().receiveEnergy(transferSpeed(), true);
//if(be.getForgeEnergy().getEnergyStored()<be.getForgeEnergy().getMaxEnergyStored()/2) {
getForgeEnergy().extractEnergy(Math.min(amount, amount2), false);
be.getForgeEnergy().receiveEnergy(Math.min(amount, amount2), false);
//}
}
}
}
default void useEnergy(int baseValue){
getForgeEnergy().extractEnergy(baseValue/(voltageGeneration()+1),false);
}
default TFMGForgeEnergyStorage createEnergyStorage(){
return new TFMGForgeEnergyStorage(FECapacity(), 99999) {
@Override
public void onEnergyChanged(int energyAmount,boolean setEnergy) {
if(setEnergy)
return;
gotFElastTick(1);
sendStuff();
}
};
}
default void writeElectrity(CompoundTag compound){
compound.putInt("Voltage",getVoltage());
compound.putInt("Current",getCurrent());
compound.putInt("DistanceFromSource",getDistanceFromSource());
compound.putInt("ForgeEnergy", getForgeEnergy().getEnergyStored());
}
}

View File

@@ -0,0 +1,3 @@
package com.drmangotea.createindustry.blocks.electricity.base;
public interface IHaveCables { }

View File

@@ -0,0 +1,285 @@
package com.drmangotea.createindustry.blocks.electricity.base;
import com.drmangotea.createindustry.base.util.TFMGUtils;
import com.simibubi.create.content.equipment.goggles.IHaveGoggleInformation;
import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
import com.simibubi.create.foundation.utility.Lang;
import net.minecraft.ChatFormatting;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ForgeCapabilities;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.energy.IEnergyStorage;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
import java.util.List;
public class KineticElectricBlockEntity extends KineticBlockEntity implements IHaveGoggleInformation, IElectricBlock {
public int voltage=0;
public int current =0;
private boolean gotFElastTick = false;
public int distanceFromSource = Integer.MAX_VALUE;
private LazyOptional<IEnergyStorage> lazyEnergyHandler = LazyOptional.empty();
public final TFMGForgeEnergyStorage energy = createEnergyStorage();
public KineticElectricBlockEntity(BlockEntityType<?> typeIn, BlockPos pos, BlockState state) {
super(typeIn, pos, state);
}
public void tick(){
super.tick();
energy.receiveEnergy(feGeneration(),false);
manageVoltage();
sendCharge(level,getBlockPos());
}
public TFMGForgeEnergyStorage getEnergy() {
return energy;
}
@Override
public void onLoad() {
super.onLoad();
lazyEnergyHandler = LazyOptional.of(() -> energy);
}
@Override
public void invalidateCaps() {
super.invalidateCaps();
lazyEnergyHandler.invalidate();
}
@Override
public @NotNull <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap, @Nullable Direction side) {
if (cap == ForgeCapabilities.ENERGY&&side == null) {
return lazyEnergyHandler.cast();
} else
if (cap == ForgeCapabilities.ENERGY&&hasElectricitySlot(side)) {
return lazyEnergyHandler.cast();
}
return super.getCapability(cap, side);
}
public void manageVoltage(){
if(voltageGeneration()>0) {
voltage = voltageGeneration();
distanceFromSource = 0;
}
if(distanceFromSource == Integer.MAX_VALUE)
voltage = 0;
current = energy.getEnergyStored()/(voltage+1);
if(voltage>maxVoltage()){
explode();
voltage = 0;
}
}
@Override
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
}
@Override
public float internalResistance() {
return 0;
}
@Override
public int getVoltage() {
return voltage;
}
@Override
public boolean gotFElastTick(int value) {
gotFElastTick = value == 3 ? gotFElastTick : value == 1;
return gotFElastTick;
}
@Override
public int getCurrent() {
return current;
}
@Override
public void addVoltage(float amount) {
if(voltageGeneration()>0)
return;
voltage = (int) amount;
//voltage = (int) ((getVoltage()+amount)/2);
}
public void addVoltageFromNonTFMGBlock() {
//if(voltage<250) {
// voltage = 250;
//
//}
}
@Override
public TFMGForgeEnergyStorage getForgeEnergy() {
return energy;
}
@Override
public boolean hasElectricitySlot(Direction direction) {
return false;
}
@Override
public float maxVoltage() {
return 500;
}
@Override
public void explode() {
TFMGUtils.createFireExplosion(level,null, getBlockPos(),10,1.5f);
}
@Override
public int FECapacity() {
return 5000;
}
@Override
public int getDistanceFromSource() {
return distanceFromSource;
}
@Override
public void setDistanceFromSource(int value) {
distanceFromSource = value;
sendStuff();
}
@Override
public void sendStuff() {
sendData();
setChanged();
}
@Override
public void write(CompoundTag compound, boolean clientPacket) {
super.write(compound, clientPacket);
writeElectrity(compound);
;
}
@Override
protected void read(CompoundTag compound, boolean clientPacket) {
super.read(compound, clientPacket);
voltage = compound.getInt("Voltage");
current = compound.getInt("Current");
distanceFromSource = compound.getInt("DistanceFromSource");
energy.setEnergy(compound.getInt("ForgeEnergy"));
}
@Override
public int feGeneration() {
return 0;
}
@Override
public int voltageGeneration() {
return 0;
}
@Override
public int transferSpeed() {
return 1000;
}
}

View File

@@ -0,0 +1,51 @@
package com.drmangotea.createindustry.blocks.electricity.base;
import net.minecraftforge.energy.EnergyStorage;
public abstract class TFMGForgeEnergyStorage extends EnergyStorage {
public TFMGForgeEnergyStorage(int capacity, int maxTransfer) {
super(capacity, maxTransfer);
}
@Override
public int extractEnergy(int maxExtract, boolean simulate) {
int extractedEnergy = super.extractEnergy(maxExtract, simulate);
if(extractedEnergy != 0) {
onEnergyChanged(maxExtract*-1,false);
}
return extractedEnergy;
}
@Override
public int receiveEnergy(int maxReceive, boolean simulate) {
int receiveEnergy = super.receiveEnergy(maxReceive, simulate);
if(receiveEnergy != 0) {
onEnergyChanged(receiveEnergy,false);
}
return receiveEnergy;
}
public int setEnergy(int energy) {
this.energy = energy;
if(energy>0)
onEnergyChanged(energy,true);
return 0;
}
public abstract void onEnergyChanged(int amount, boolean setEnergy);
}

View File

@@ -0,0 +1,45 @@
package com.drmangotea.createindustry.blocks.electricity.base;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.DirectionProperty;
import javax.annotation.Nullable;
public class WallMountBlock extends Block {
public static final DirectionProperty FACING = BlockStateProperties.FACING;
public WallMountBlock(Properties p_49795_) {
super(p_49795_);
// this.registerDefaultState(this.stateDefinition.any().setValue(FACING,Direction.UP));
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
super.createBlockStateDefinition(builder.add(FACING));
}
@Nullable
public BlockState getStateForPlacement(BlockPlaceContext p_58126_) {
BlockState blockstate = this.defaultBlockState();
LevelReader levelreader = p_58126_.getLevel();
BlockPos blockpos = p_58126_.getClickedPos();
Direction[] adirection = p_58126_.getNearestLookingDirections();
for(Direction direction : adirection) {
Direction direction1 = direction.getOpposite();
blockstate = blockstate.setValue(FACING, direction1);
if (blockstate.canSurvive(levelreader, blockpos)) {
return blockstate;
}
}
return null;
}
}

View File

@@ -0,0 +1,96 @@
package com.drmangotea.createindustry.blocks.electricity.base.cables;
import com.drmangotea.createindustry.CreateTFMG;
import com.drmangotea.createindustry.blocks.electricity.base.IHaveCables;
import com.drmangotea.createindustry.blocks.electricity.base.WallMountBlock;
import com.drmangotea.createindustry.registry.TFMGBlockEntities;
import com.drmangotea.createindustry.registry.TFMGItems;
import com.drmangotea.createindustry.registry.TFMGShapes;
import com.simibubi.create.content.equipment.wrench.IWrenchable;
import com.simibubi.create.foundation.block.IBE;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.world.level.storage.loot.LootContext;
import net.minecraft.world.level.storage.loot.LootTable;
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets;
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public class CableConnectorBlock extends WallMountBlock implements IBE<CableConnectorBlockEntity>, IHaveCables, IWrenchable {
public static final BooleanProperty EXTENSION = BooleanProperty.create("extension");
public CableConnectorBlock(Properties p_49795_) {
super(p_49795_);
registerDefaultState(defaultBlockState().setValue(EXTENSION, false));
}
@Override
public VoxelShape getShape(BlockState pState, BlockGetter worldIn, BlockPos pos, CollisionContext context) {
if(pState.getValue(EXTENSION))
return TFMGShapes.CABLE_CONNECTOR_MIDDLE.get(pState.getValue(FACING));
return TFMGShapes.CABLE_CONNECTOR.get(pState.getValue(FACING));
}
@Override
public InteractionResult onWrenched(BlockState state, UseOnContext context) {
Level level = context.getLevel();
BlockPos pos = context.getClickedPos();
Direction direction = context.getClickedFace();
return onBlockEntityUse(level, pos, be -> {
be.sendStuff();
return InteractionResult.SUCCESS;
});
}
@Override
public void onRemove(BlockState state, Level worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
IBE.onRemove(state, worldIn, pos, newState);
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
super.createBlockStateDefinition(builder);
builder.add(EXTENSION);
}
@Override
public Class<CableConnectorBlockEntity> getBlockEntityClass() {
return CableConnectorBlockEntity.class;
}
@Override
public BlockEntityType<? extends CableConnectorBlockEntity> getBlockEntityType() {
return TFMGBlockEntities.CABLE_CONNECTOR.get();
}
}

View File

@@ -0,0 +1,407 @@
package com.drmangotea.createindustry.blocks.electricity.base.cables;
import com.drmangotea.createindustry.CreateTFMG;
import com.drmangotea.createindustry.base.TFMGTools;
import com.drmangotea.createindustry.blocks.electricity.base.*;
import com.drmangotea.createindustry.blocks.electricity.resistors.ResistorBlockEntity;
import com.drmangotea.createindustry.registry.TFMGItems;
import com.simibubi.create.Create;
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
import com.simibubi.create.foundation.utility.Lang;
import net.minecraft.ChatFormatting;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import net.minecraftforge.common.capabilities.ForgeCapabilities;
import net.minecraftforge.energy.EnergyStorage;
import java.util.ArrayList;
import java.util.List;
public class CableConnectorBlockEntity extends ElectricBlockEntity {
Player player = null;
public ArrayList<WireConnection> wireConnections = new ArrayList<>();
public CableConnectorBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
}
@Override
public float maxVoltage() {
return 6000;
}
public void tick(){
super.tick();
updateBlockBelow();
spreadCurrent();
//
sendData();
setChanged();
//
if(Create.RANDOM.nextBoolean())
removeInvalidConnections();
changeToExtension();
}
@Override
public void destroy() {
super.destroy();
ItemEntity itemToSpawn = new ItemEntity((Level) level, getBlockPos().getX() + 0.5f, getBlockPos().getY() + 0.5f, getBlockPos().getZ() + 0.5f, new ItemStack(TFMGItems.COPPER_CABLE.get(),wireConnections.toArray().length));
if(itemToSpawn.getItem().getCount()==0)
return;
level.addFreshEntity(itemToSpawn);
}
public void changeToExtension(){
BlockState state = level.getBlockState(getBlockPos().relative(getBlockState().getValue(WallMountBlock.FACING)));
if(state.getBlock() == getBlockState().getBlock()){
if(state.getValue(WallMountBlock.FACING)==getBlockState().getValue(WallMountBlock.FACING))
if(!getBlockState().getValue(CableConnectorBlock.EXTENSION))
level.setBlock(getBlockPos(),getBlockState().setValue(CableConnectorBlock.EXTENSION,true),2);
} else
if(getBlockState().getValue(CableConnectorBlock.EXTENSION))
level.setBlock(getBlockPos(),getBlockState().setValue(CableConnectorBlock.EXTENSION,false),2);
}
public void removeInvalidConnections(){
wireConnections.removeIf(connection -> !(level.getBlockState(connection.point1).getBlock() instanceof IHaveCables)
|| !(level.getBlockState(connection.point2).getBlock() instanceof IHaveCables));
}
@Override
public void write(CompoundTag compound, boolean clientPacket) {
super.write(compound, clientPacket);
int value = 0;
for(WireConnection connection : wireConnections){
value++;
connection.saveConnection(compound,value-1);
}
compound.putInt("WireCount",wireConnections.toArray().length);
}
@Override
protected void read(CompoundTag compound, boolean clientPacket) {
super.read(compound, clientPacket);
// sendData();
addConnection(WireManager.Conductor.COPPER,getBlockPos().above(2).north(),true);
// wireConnections.add(new WireConnection(WireManager.Conductor.COPPER,1,getBlockPos().above(2).north(),this.getBlockPos(),true));
if(wireConnections.isEmpty())
return;
wireConnections = new ArrayList<>();
for(int i = 0; i < compound.getInt("WireCount");i++){
// level.setBlock(getBlockPos().above(1+i),Blocks.REINFORCED_DEEPSLATE.defaultBlockState(),3);
BlockPos pos = new BlockPos(compound.getInt("X1"+i),compound.getInt("Y1"+i),compound.getInt("Z1"+i));
// level.setBlock(new BlockPos(compound.getInt("X1"+i),compound.getInt("Y1"+i),compound.getInt("Z1"+i)), Blocks.REINFORCED_DEEPSLATE.defaultBlockState(),3);
if(pos == this.getBlockPos())
pos = new BlockPos(compound.getInt("X2"+i),compound.getInt("Y2"+i),compound.getInt("Z2"+i));
// level.setBlock(new BlockPos(compound.getInt("X2"+i),compound.getInt("Y2"+i),compound.getInt("Z2"+i)), Blocks.GOLD_BLOCK.defaultBlockState(),3);
// CreateTFMG.LOGGER.debug(" X: "+pos.getX()+" Y: "+pos.getY()+" Z: "+pos.getZ());
addConnection(WireManager.Conductor.COPPER,pos,compound.getBoolean("ShouldRender"+i));
}
}
@Override
public void sendCharge(Level level, BlockPos pos){
int lowestDistance = Integer.MAX_VALUE;
boolean getsVoltageFromNonTFMGBlock = false;
for(Direction direction : Direction.values()){
if(hasElectricitySlot(direction)){
BlockEntity be1 =level.getBlockEntity(pos.relative(direction));
if(be1 instanceof IElectricBlock be2){
if(be2.hasElectricitySlot(direction.getOpposite())) {
int distance = be2.getDistanceFromSource();
if(!isStorage()&&be2.isStorage()&&direction == Direction.UP)
distance = Integer.MAX_VALUE;
if(getVoltage()==0) {
if(distance>getDistanceFromSource())
be2.addVoltage(getVoltage());
}
if(!(isStorage()&&direction == Direction.DOWN))
if(!(!isStorage()&&be2.isStorage()&&direction == Direction.DOWN))
if(getVoltage()!=0) {
// if(Create.RANDOM.nextInt(3)==2)
transferCharge(be2);
if(distance>getDistanceFromSource()){
be2.addVoltage(getVoltage());
}
}
lowestDistance = Math.min(lowestDistance,distance);
}
if(direction.getAxis().isHorizontal()) {
if (be2 instanceof ResistorBlockEntity resistorBE)
if (resistorBE.hasElectricitySlot(direction) && resistorBE.getVoltageOutput() > 0) {
lowestDistance = 0;
addVoltage(resistorBE.getVoltageOutput());
}
}
}else
if(be1!=null) {
if (be1.getCapability(ForgeCapabilities.ENERGY, direction.getOpposite()).isPresent() && getForgeEnergy().getEnergyStored() > 0) {
if (!(be1.getCapability(ForgeCapabilities.ENERGY).orElse(new EnergyStorage(0)) instanceof TFMGForgeEnergyStorage)
&& be1.getCapability(ForgeCapabilities.ENERGY).orElse(new EnergyStorage(0)).getEnergyStored() > 0 &&
be1.getCapability(ForgeCapabilities.ENERGY, direction.getOpposite()).orElse(new EnergyStorage(0)).canReceive()
) {
// lowestDistance = 0;
// setDistanceFromSource(1);
// getsVoltageFromNonTFMGBlock = true;
}
}
}
}
}
for(WireConnection connection : wireConnections){
BlockPos pos1 = connection.point1 == getBlockPos() ? connection.point2 : connection.point1;
if(level.getBlockEntity(pos1) instanceof CableConnectorBlockEntity)
lowestDistance = Math.min(lowestDistance,((CableConnectorBlockEntity)level.getBlockEntity(pos1)).getDistanceFromSource());
}
if (lowestDistance != Integer.MAX_VALUE&&voltageGeneration()==0) {
if( lowestDistance >= getDistanceFromSource()){
}else {
if(Create.RANDOM.nextInt(2)==0)
setDistanceFromSource(lowestDistance + 1);
}
//sendStuff();
}
//else distanceFromSource = Integer.MAX_VALUE;
if(voltageGeneration()>0){
setDistanceFromSource(0);
//sendStuff();
}
if(!level.isClientSide)
if(lowestDistance == getDistanceFromSource()+1&&this.voltageGeneration()==0&&!getsVoltageFromNonTFMGBlock){
setDistanceFromSource(Integer.MAX_VALUE);
// sendStuff();
}
if(!level.isClientSide)
if(getDistanceFromSource()<lowestDistance&&getDistanceFromSource() >0&&this.voltageGeneration()==0&&!getsVoltageFromNonTFMGBlock){
setDistanceFromSource(Integer.MAX_VALUE);
// sendStuff();
//
}
if(!level.isClientSide)
if(lowestDistance == Integer.MAX_VALUE && voltageGeneration() == 0&&!getsVoltageFromNonTFMGBlock){
setDistanceFromSource(Integer.MAX_VALUE);
// sendStuff();
}
//if(voltageGeneration()>0)
// setDistanceFromSource(0);
if(lowestDistance>=getDistanceFromSource()&&getDistanceFromSource()!=0)
setDistanceFromSource(Integer.MAX_VALUE);
if(getDistanceFromSource()==Integer.MAX_VALUE)
addVoltage(0);
}
public void spreadCurrent(){
for(WireConnection connection : wireConnections){
BlockPos pos = connection.point1;
if(connection.point1 == this.getBlockPos())
pos = connection.point2;
if(level.getBlockEntity(pos) instanceof CableConnectorBlockEntity be) {
transferCharge(be);
if(be.getDistanceFromSource()>getDistanceFromSource())
be.addVoltage(getVoltage());
///
BlockPos pos2 = pos == connection.point1 ? connection.point2 : connection.point1;
CableConnectorBlockEntity be2= this;
if(level.getBlockEntity(pos2) instanceof CableConnectorBlockEntity)
be2= (CableConnectorBlockEntity) level.getBlockEntity(pos2);
///
// //if(be.getDistanceFromSource() == Integer.MAX_VALUE){
// if(getDistanceFromSource() != Integer.MAX_VALUE) {
// // be.setDistanceFromSource(getDistanceFromSource() + 1);
// be.setDistanceFromSource(Create.RANDOM.nextInt(200));
// be2.sendStuff();
// be.sendStuff();
// be2.updateBlockBelow();
// be.updateBlockBelow();
//
// // level.setBlock(be.getBlockPos(),Blocks.DIAMOND_BLOCK.defaultBlockState(),3);
// // level.setBlock(be2.getBlockPos(),Blocks.GOLD_BLOCK.defaultBlockState(),3);
//
// }
// // }
}
}
}
public void updateBlockBelow(){
if(level.getBlockEntity(getBlockPos().relative(getBlockState().getValue(WallMountBlock.FACING).getOpposite())) instanceof IElectricBlock be){
be.sendStuff();
}
}
@Override
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
}
@Override
protected AABB createRenderBoundingBox() {
return new AABB(this.getBlockPos()).inflate(30);
}
public boolean addConnection(WireManager.Conductor material, BlockPos pos,boolean shouldRender){
float lenght = TFMGTools.getDistance(this.getBlockPos(),pos,false);
if(lenght<25) {
wireConnections.add(new WireConnection(material, lenght, pos, this.getBlockPos(), shouldRender));
sendData();
setChanged();
return true;
}else {
sendData();
setChanged();
return false;
}
}
@Override
public boolean hasElectricitySlot(Direction direction) {
return direction == getBlockState().getValue(WallMountBlock.FACING).getOpposite();
}
}

View File

@@ -0,0 +1,76 @@
package com.drmangotea.createindustry.blocks.electricity.base.cables;
import com.drmangotea.createindustry.blocks.electricity.base.WallMountBlock;
import com.simibubi.create.foundation.data.AssetLookup;
import com.simibubi.create.foundation.data.SpecialBlockStateGen;
import com.tterrag.registrate.providers.DataGenContext;
import com.tterrag.registrate.providers.RegistrateBlockstateProvider;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.client.model.generators.ModelFile;
public class CableConnectorGenerator extends SpecialBlockStateGen {
public CableConnectorGenerator() {
}
protected int getXRotation(BlockState state) {
short value;
switch ((Direction)state.getValue(WallMountBlock.FACING)) {
case NORTH:
value = 90;
break;
case SOUTH:
value = 90;
break;
case WEST:
value = 90;
break;
case EAST:
value = 90;
break;
case DOWN:
value = 180;
break;
case UP:
value = 0;
break;
default:
throw new IncompatibleClassChangeError();
}
return value;
}
protected int getYRotation(BlockState state) {
short value;
switch ((Direction)state.getValue(WallMountBlock.FACING)) {
case NORTH:
value = 0;
break;
case SOUTH:
value = 180;
break;
case WEST:
value = 270;
break;
case EAST:
value = 90;
break;
case DOWN:
value = 0;
break;
case UP:
value = 0;
break;
default:
throw new IncompatibleClassChangeError();
}
return value;
}
public <T extends Block> ModelFile getModel(DataGenContext<Block, T> ctx, RegistrateBlockstateProvider prov, BlockState state) {
return (Boolean)state.getValue(CableConnectorBlock.EXTENSION) ? AssetLookup.partialBaseModel(ctx, prov, new String[]{"extension"}) : AssetLookup.partialBaseModel(ctx, prov, new String[0]);
}
}

View File

@@ -0,0 +1,32 @@
package com.drmangotea.createindustry.blocks.electricity.base.cables;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.foundation.blockEntity.renderer.SafeBlockEntityRenderer;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import net.minecraft.core.BlockPos;
public class CableConnectorRenderer extends SafeBlockEntityRenderer<CableConnectorBlockEntity> {
public CableConnectorRenderer(BlockEntityRendererProvider.Context context) {
}
@Override
protected void renderSafe(CableConnectorBlockEntity be, float partialTicks, PoseStack ms, MultiBufferSource bufferSource, int light, int overlay) {
for(WireConnection wireConnection : be.wireConnections){
if(wireConnection.shouldRender)
WireManager.renderWire(ms,bufferSource,wireConnection.point1,wireConnection.point2,0,0,0,0,0,0, wireConnection.lenght/4500);
}
//if(be.player !=null){
// BlockPos pos = new BlockPos(be.player.getX(),be.player.getY(),be.player.getZ());
//
// WireManager.renderWire(ms,bufferSource,pos,be.getBlockPos(),0,0,0,0,0,0, 10f/4500f);
//
//}
}
}

View File

@@ -0,0 +1,53 @@
package com.drmangotea.createindustry.blocks.electricity.base.cables;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
public class WireConnection {
public final WireManager.Conductor material;
public final float lenght;
public final float resistance;
public static final float CABLE_THICKNESS = 1.5f;
public final BlockPos point1;
public final BlockPos point2;
public final boolean shouldRender;
public WireConnection(WireManager.Conductor material, float lenght,BlockPos point1, BlockPos point2, boolean render){
this.material = material;
this.lenght = lenght;
this.point1 = point1;
this.point2 = point2;
this.shouldRender = render;
this.resistance = material.resistivity*(lenght/CABLE_THICKNESS);
}
public void saveConnection(CompoundTag compound,int value){
compound.putInt("X1"+value,point1.getX());
compound.putInt("Y1"+value,point1.getY());
compound.putInt("Z1"+value,point1.getZ());
compound.putInt("X2"+value,point2.getX());
compound.putInt("Y2"+value,point2.getY());
compound.putInt("Z2"+value,point2.getZ());
compound.putFloat("Lenght"+value,lenght);
compound.putBoolean("ShouldRender"+value,shouldRender);
compound.putString("Material"+value, material.name());
}
}

View File

@@ -0,0 +1,196 @@
package com.drmangotea.createindustry.blocks.electricity.base.cables;
import com.drmangotea.createindustry.blocks.electricity.base.IHaveCables;
import com.drmangotea.createindustry.items.weapons.advanced_potato_cannon.AdvancedPotatoCannonItemRenderer;
import com.drmangotea.createindustry.registry.TFMGItems;
import com.simibubi.create.foundation.item.render.SimpleCustomRenderer;
import com.simibubi.create.foundation.utility.Lang;
import net.minecraft.ChatFormatting;
import net.minecraft.core.BlockPos;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.InteractionResultHolder;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.extensions.common.IClientItemExtensions;
import java.util.function.Consumer;
public class WireItem extends Item {
public WireManager.Conductor material;
public WireItem(Properties p_41383_, WireManager.Conductor material) {
super(p_41383_);
this.material = material;
}
public InteractionResult useOn(UseOnContext context) {
Level level = context.getLevel();
BlockPos pos = context.getClickedPos();
BlockState state = level.getBlockState(pos);
ItemStack stack = context.getItemInHand();
Player player = context.getPlayer();
if(state.getBlock() instanceof IHaveCables){
if(stack.getOrCreateTag().getInt("X1")!=0&&
stack.getOrCreateTag().getInt("Y1")!=0&&
stack.getOrCreateTag().getInt("Z1")!=0
){
boolean placeWire = true;
if(level.getBlockEntity(pos)!=null)
if(level.getBlockEntity(pos) instanceof CableConnectorBlockEntity be){
if(testConnection(stack,be,pos)) {
BlockPos pos2 = new BlockPos(stack.getOrCreateTag().getInt("X1"), stack.getOrCreateTag().getInt("Y1"), stack.getOrCreateTag().getInt("Z1"));
if(level.getBlockEntity(pos2) instanceof CableConnectorBlockEntity be2) {
if(be2.getBlockPos() == be.getBlockPos())
return InteractionResult.PASS;
if(be.getBlockState().getValue(CableConnectorBlock.EXTENSION)||be2.getBlockState().getValue(CableConnectorBlock.EXTENSION))
return InteractionResult.PASS;
be.addConnection(material, pos2, true);
be.sendData();
be.setChanged();
be2.addConnection(material, pos, false);
be2.sendData();
be2.setChanged();
}
}
}
if(state.getValue(CableConnectorBlock.EXTENSION))
return InteractionResult.PASS;
stack.getOrCreateTag().putInt("X1",0);
stack.getOrCreateTag().putInt("Y1",0);
stack.getOrCreateTag().putInt("Z1",0);
if(player.isCreative()) {
player.setItemInHand(context.getHand(), new ItemStack(TFMGItems.COPPER_CABLE.get(), stack.getCount()));
}else player.setItemInHand(context.getHand(), new ItemStack(TFMGItems.COPPER_CABLE.get(), stack.getCount() - 1));
//if(!placeWire)
// player.kill();
return InteractionResult.SUCCESS;
}
stack.getOrCreateTag().putInt("X1",pos.getX());
stack.getOrCreateTag().putInt("Y1",pos.getY());
stack.getOrCreateTag().putInt("Z1",pos.getZ());
if(level.getBlockEntity(pos) instanceof CableConnectorBlockEntity connector)
connector.player = player;
return InteractionResult.SUCCESS;
}
return super.useOn(context);
}
@Override
public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand hand) {
ItemStack stack = player.getItemInHand(hand);
if(player.isCrouching()){
BlockPos pos = new BlockPos(stack.getOrCreateTag().getInt("X1"),stack.getOrCreateTag().getInt("Y1"),stack.getOrCreateTag().getInt("Z1"));
if(level.getBlockEntity(pos) instanceof CableConnectorBlockEntity be){
be.player = null;
}
stack = new ItemStack(stack.getItem(),stack.getCount());
if (!level.isClientSide)
player.displayClientMessage(Lang.translateDirect("wires.removed_data")
.withStyle(ChatFormatting.YELLOW), true);
return InteractionResultHolder.success(stack);
}
return super.use(level, player, hand);
}
private boolean testConnection(ItemStack stack, CableConnectorBlockEntity be, BlockPos pos) {
for(WireConnection connection : be.wireConnections){
if(
connection.point1.getX() == stack.getOrCreateTag().getInt("X1")&&
connection.point1.getY() == stack.getOrCreateTag().getInt("Y1")&&
connection.point1.getZ() == stack.getOrCreateTag().getInt("Z1")&&
connection.point2.getX() == pos.getX()&&
connection.point2.getY() == pos.getY()&&
connection.point2.getZ() == pos.getZ()
){
return false;
}
if(
connection.point2.getX() == stack.getOrCreateTag().getInt("X1")&&
connection.point2.getY() == stack.getOrCreateTag().getInt("Y1")&&
connection.point2.getZ() == stack.getOrCreateTag().getInt("Z1")&&
connection.point1.getX() == pos.getX()&&
connection.point1.getY() == pos.getY()&&
connection.point1.getZ() == pos.getZ()
){
return false;
}
}
return true;
}
}

View File

@@ -0,0 +1,129 @@
package com.drmangotea.createindustry.blocks.electricity.base.cables;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.math.Matrix4f;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.core.BlockPos;
import net.minecraft.util.Mth;
import net.minecraft.util.StringRepresentable;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.LightLayer;
import net.minecraft.world.phys.Vec3;
public class WireManager {
public static void renderWire(PoseStack pMatrixStack, MultiBufferSource pBuffer, BlockPos pos1, BlockPos pos2,
float offsetX1,float offsetY1,float offsetZ1,float offsetX2,float offsetY2,float offsetZ2,float curve) {
pMatrixStack.pushPose();
Vec3 vec3 = new Vec3(0,0,0);
BlockPos pos2Local = pos1.subtract(pos2);
pMatrixStack.translate(0.5+offsetX1, 0.5+offsetY1, 0.5+offsetZ1);
vec3 = vec3.add(pos2Local.getX()-offsetX1+offsetX2+0.01,pos2Local.getY()-offsetY1+offsetY2,pos2Local.getZ()-offsetZ1+offsetZ2+0.01);
float f = (float)(vec3.x);
float f1 = (float)(vec3.y );
float f2 = (float)(vec3.z);
VertexConsumer vertexconsumer = pBuffer.getBuffer(RenderType.leash());
Matrix4f matrix4f = pMatrixStack.last().pose();
float f4 = Mth.fastInvSqrt(f * f + f2 * f2) * 0.025F / 2.0F;
float f5 = f2 * f4;
float f6 = f * f4;
int i =15;
int j = 15;
//int i = this.getBlockLightLevel(pEntityLiving, blockpos);
//int j = this.entityRenderDispatcher.getRenderer(pLeashHolder).getBlockLightLevel(pLeashHolder, blockpos1);
//int k = pEntityLiving.level.getBrightness(LightLayer.SKY, blockpos);
//int l = pEntityLiving.level.getBrightness(LightLayer.SKY, blockpos1);
int k = 15;
int l = 15;
for(int i1 = 0; i1 <= 24; ++i1) {
addVertexPair(vertexconsumer, matrix4f, f, f1, f2, i, j, k, l, 0.030F, 0.030F, f5, f6, i1, false,curve);
}
for(int j1 = 24; j1 >= 0; --j1) {
addVertexPair(vertexconsumer, matrix4f, f, f1, f2, i, j, k, l, 0.030F, 0.00F, f5, f6, j1, true,curve);
}
pMatrixStack.popPose();
}
private static void addVertexPair(VertexConsumer vertexConsumer, Matrix4f matrix4f, float p_174310_, float p_174311_, float p_174312_, int p_174313_, int p_174314_, int p_174315_, int p_174316_, float thickness, float p_174318_, float p_174319_, float p_174320_, int value, boolean p_174322_, float curve) {
float f = (float)(value / 24.0F);
int i = (int)Mth.lerp(f, (float)p_174313_, (float)p_174314_);
int j = (int)Mth.lerp(f, (float)p_174315_, (float)p_174316_);
int k = LightTexture.pack(i, j);
float f1 = value % 2 == (p_174322_ ? 1 : 0) ? 0.7F : 1.0F;
float red = 0.1F * f1;
float green = 0.1F * f1;
float blue = 0.1F * f1;
float x = p_174310_ * f;
float pain;
pain = ((value*curve*24)-(value*value*curve)) * -1f;
float y = p_174311_ > 0.0F ? p_174311_ * f * f : p_174311_ - p_174311_ * (1.0F - f) * (1.0F - f);
float z = p_174312_ * f;
vertexConsumer.vertex(matrix4f, x - p_174319_, y + p_174318_+pain, z + p_174320_).color(red, green, blue, 1.0F).uv2(k).endVertex();
vertexConsumer.vertex(matrix4f, x + p_174319_, y + thickness - p_174318_+pain, z - p_174320_).color(red, green, blue, 1.0F).uv2(k).endVertex();
}
public enum Conductor implements StringRepresentable {
COPPER(0.0178f,"copper")
;
public float resistivity;
private String name;
Conductor(float resistivity, String name){
this.resistivity = resistivity;
this.name = name;
}
public float getResistivity() {
return resistivity;
}
@Override
public String getSerializedName() {
return null;
}
}
}

View File

@@ -0,0 +1,13 @@
package com.drmangotea.createindustry.blocks.electricity.base.multimeter;
import net.minecraft.world.item.Item;
public class MultimeterItem extends Item {
public MultimeterItem(Properties p_41383_) {
super(p_41383_);
}
}

View File

@@ -0,0 +1,55 @@
package com.drmangotea.createindustry.blocks.electricity.batteries;
import com.drmangotea.createindustry.registry.TFMGBlockEntities;
import com.simibubi.create.content.equipment.wrench.IWrenchable;
import com.simibubi.create.foundation.block.IBE;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import javax.annotation.Nullable;
public class BatteryBlock extends Block implements IBE<BatteryBlockEntity>, IWrenchable {
public BatteryBlock(Properties p_49795_) {
super(p_49795_);
}
@Override
public void setPlacedBy(Level level, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) {
super.setPlacedBy(level, pos, state, placer, stack);
withBlockEntityDo(level, pos, be -> be.setCapacity(stack));
}
public void playerDestroy(Level level, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity be, ItemStack stack) {
int capacity = 0;
if(be !=null)
if(be instanceof BatteryBlockEntity be1)
capacity = be1.capacity;
stack.getOrCreateTag().putInt("Capacity",capacity);
super.playerDestroy(level,player,pos,state,be,stack);
}
@Override
public Class<BatteryBlockEntity> getBlockEntityClass() {
return BatteryBlockEntity.class;
}
@Override
public BlockEntityType<? extends BatteryBlockEntity> getBlockEntityType() {
//return TFMGBlockEntities.ACCUMULATOR.get();
return null;
}
}

View File

@@ -0,0 +1,93 @@
package com.drmangotea.createindustry.blocks.electricity.batteries;
import com.drmangotea.createindustry.blocks.electricity.base.ElectricBlockEntity;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import java.util.List;
public class BatteryBlockEntity extends ElectricBlockEntity {
public float powerOutput = 0;
public int capacity = 0;
public BatteryBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
}
public void setCapacity(ItemStack stack){
//capacity = stack.getOrCreateTag().getInt("Capacity");
energy.receiveEnergy(stack.getOrCreateTag().getInt("Capacity"),false);
}
public void tick(){
super.tick();
if(capacity>0) {
powerOutput = transferSpeed();
}else powerOutput = 0;
}
@Override
public int transferSpeed() {
return 100;
}
@Override
public boolean addToGoggleTooltip(List<Component> tooltip, boolean isPlayerSneaking) {
return true;
}
@Override
public void write(CompoundTag compound, boolean clientPacket) {
compound.putInt("Capacity", capacity);
super.write(compound, clientPacket);
}
@Override
protected void read(CompoundTag compound, boolean clientPacket) {
super.read(compound, clientPacket);
capacity = compound.getInt("Capacity");
}
@Override
public boolean hasElectricitySlot(Direction direction) {
if(direction == Direction.UP)
return true;
return false;
}
@Override
public int FECapacity() {
return 30000;
}
@Override
public int voltageGeneration() {
return energy.getEnergyStored() <= 10 ? 0 : 200;
}
}

View File

@@ -0,0 +1,62 @@
package com.drmangotea.createindustry.blocks.electricity.batteries;
import com.drmangotea.createindustry.blocks.TFMGHorizontalDirectionalBlock;
import com.drmangotea.createindustry.registry.TFMGBlockEntities;
import com.drmangotea.createindustry.registry.TFMGShapes;
import com.simibubi.create.foundation.block.IBE;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
import javax.annotation.Nullable;
public class GalvanicCellBlock extends TFMGHorizontalDirectionalBlock implements IBE<GalvanicCellBlockEntity> {
public GalvanicCellBlock(Properties p_54120_) {
super(p_54120_);
}
@Override
public VoxelShape getShape(BlockState pState, BlockGetter worldIn, BlockPos pos, CollisionContext context) {
return TFMGShapes.GALVANIC_CELL.get(pState.getValue(FACING));
}
@Override
public void setPlacedBy(Level level, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) {
super.setPlacedBy(level, pos, state, placer, stack);
withBlockEntityDo(level, pos, be -> be.setCapacity(stack));
}
public void playerDestroy(Level level, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity be, ItemStack stack) {
int capacity = 0;
if(be !=null)
if(be instanceof BatteryBlockEntity be1)
capacity = be1.capacity;
stack.getOrCreateTag().putInt("Capacity",capacity);
super.playerDestroy(level,player,pos,state,be,stack);
}
@Override
public Class<GalvanicCellBlockEntity> getBlockEntityClass() {
return GalvanicCellBlockEntity.class;
}
@Override
public BlockEntityType<? extends GalvanicCellBlockEntity> getBlockEntityType() {
return TFMGBlockEntities.GALVANIC_CELL.get();
}
}

View File

@@ -0,0 +1,32 @@
package com.drmangotea.createindustry.blocks.electricity.batteries;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import static net.minecraft.world.level.block.HorizontalDirectionalBlock.FACING;
public class GalvanicCellBlockEntity extends BatteryBlockEntity {
public GalvanicCellBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
}
@Override
public boolean hasElectricitySlot(Direction direction) {
return direction == getBlockState().getValue(FACING);
}
@Override
public int FECapacity() {
return 200000;
}
}

View File

@@ -0,0 +1,23 @@
package com.drmangotea.createindustry.blocks.electricity.cable_blocks;
import com.drmangotea.createindustry.registry.TFMGBlockEntities;
import com.simibubi.create.content.equipment.wrench.IWrenchable;
import com.simibubi.create.foundation.block.IBE;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntityType;
public class CableHubBlock extends Block implements IBE<CableHubBlockEntity>, IWrenchable {
public CableHubBlock(Properties p_49795_) {
super(p_49795_);
}
@Override
public Class<CableHubBlockEntity> getBlockEntityClass() {
return CableHubBlockEntity.class;
}
@Override
public BlockEntityType<? extends CableHubBlockEntity> getBlockEntityType() {
return TFMGBlockEntities.CABLE_HUB.get();
}
}

View File

@@ -0,0 +1,138 @@
package com.drmangotea.createindustry.blocks.electricity.cable_blocks;
import com.drmangotea.createindustry.blocks.electricity.base.ElectricBlockEntity;
import com.drmangotea.createindustry.blocks.electricity.base.IElectricBlock;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.common.capabilities.ForgeCapabilities;
import java.util.ArrayList;
public class CableHubBlockEntity extends ElectricBlockEntity {
int signal;
boolean signalChanged;
byte[] directions = new byte[6];
public CableHubBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
neighbourChanged();
}
@Override
public boolean hasElectricitySlot(Direction direction) {
return true;
}
@Override
public void tick() {
if (signalChanged) {
signalChanged = false;
analogSignalChanged(level.getBestNeighborSignal(worldPosition));
}
super.tick();
}
public void neighbourChanged() {
if (!hasLevel())
return;
ArrayList<Byte> list = new ArrayList<>();
// for(Direction direction1 : Direction.values()) {
// if(level.getBlockEntity(getBlockPos().relative(direction1))instanceof IElectricBlock be){
// if(be.hasElectricitySlot(direction1.getOpposite())){
// list.add((byte) 1);
// }else list.add((byte) 0);
//
// }else {
// if(level.getBlockEntity(getBlockPos().relative(direction1))==null){
// list.add((byte) 0);
// continue;
// }
//
//
// if (level.getBlockEntity(getBlockPos().relative(direction1)).getCapability(ForgeCapabilities.ENERGY).isPresent()) {
// list.add((byte) 1);
// } else list.add((byte) 0);
//
// }
// }
//
// directions = new byte[]{list.get(0),list.get(1),list.get(2),list.get(3),list.get(4),list.get(5)};
int power = level.getBestNeighborSignal(worldPosition);
if (power != signal)
signalChanged = true;
}
@Override
public void lazyTick() {
super.lazyTick();
neighbourChanged();
}
protected void analogSignalChanged(int newSignal) {
//removeSource();
signal = newSignal;
}
@Override
public boolean hasSignal() {
return signal>0;
}
@Override
public float maxVoltage() {
return 6000;
}
@Override
public void write(CompoundTag compound, boolean clientPacket) {
compound.putInt("Signal", signal);
compound.putByteArray("Directions",directions);
super.write(compound, clientPacket);
}
@Override
protected void read(CompoundTag compound, boolean clientPacket) {
signal = compound.getInt("Signal");
directions = compound.getByteArray("Directions");
super.read(compound, clientPacket);
}
@Override
public boolean canBeDisabled() {
return true;
}
}

View File

@@ -0,0 +1,138 @@
package com.drmangotea.createindustry.blocks.electricity.cable_blocks;
import com.drmangotea.createindustry.blocks.electricity.lights.neon.NeonTubeBlock;
import com.drmangotea.createindustry.blocks.electricity.lights.neon.NeonTubeBlockEntity;
import com.drmangotea.createindustry.registry.TFMGBlockEntities;
import com.drmangotea.createindustry.registry.TFMGBlocks;
import com.drmangotea.createindustry.registry.TFMGShapes;
import com.simibubi.create.foundation.block.IBE;
import com.simibubi.create.foundation.placement.IPlacementHelper;
import com.simibubi.create.foundation.placement.PlacementHelpers;
import com.simibubi.create.foundation.placement.PlacementOffset;
import com.simibubi.create.foundation.placement.PoleHelper;
import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.DyeColor;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.RotatedPillarBlock;
import net.minecraft.world.level.block.SimpleWaterloggedBlock;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.material.Fluids;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
import java.util.function.Predicate;
public class CableTubeBlock extends RotatedPillarBlock implements IBE<CableTubeBlockEntity>, SimpleWaterloggedBlock {
public static final int placementHelperId = PlacementHelpers.register(new PlacementHelper());
public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED;
public CableTubeBlock(Properties p_49795_) {
super(p_49795_);
this.registerDefaultState(this.stateDefinition.any().setValue(WATERLOGGED, Boolean.FALSE).setValue(AXIS, Direction.Axis.Y));
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
builder.add(WATERLOGGED);
super.createBlockStateDefinition(builder);
}
@Override
public BlockState updateShape(BlockState p_51461_, Direction p_51462_, BlockState p_51463_, LevelAccessor p_51464_, BlockPos p_51465_, BlockPos p_51466_) {
if (p_51461_.getValue(WATERLOGGED)) {
p_51464_.scheduleTick(p_51465_, Fluids.WATER, Fluids.WATER.getTickDelay(p_51464_));
}
return super.updateShape(p_51461_, p_51462_, p_51463_, p_51464_, p_51465_, p_51466_);
}
@Override
public VoxelShape getShape(BlockState pState, BlockGetter pLevel, BlockPos pPos, CollisionContext pContext) {
return TFMGShapes.CABLE_TUBE.get(pState.getValue(AXIS));
}
public BlockState getStateForPlacement(BlockPlaceContext context) {
FluidState fluidstate = context.getLevel().getFluidState(context.getClickedPos());
boolean flag = fluidstate.getType() == Fluids.WATER;
return this.defaultBlockState().setValue(AXIS, context.getClickedFace().getAxis()).setValue(WATERLOGGED, flag);
}
@Override
public Class<CableTubeBlockEntity> getBlockEntityClass() {
return CableTubeBlockEntity.class;
}
@Override
public BlockEntityType<? extends CableTubeBlockEntity> getBlockEntityType() {
return TFMGBlockEntities.CABLE_TUBE.get();
}
@Override
public InteractionResult use(BlockState pState, Level pLevel, BlockPos pPos, Player player, InteractionHand pHand,
BlockHitResult pHit) {
ItemStack itemInHand = player.getItemInHand(pHand);
IPlacementHelper helper = PlacementHelpers.get(placementHelperId);
if (helper.matchesItem(itemInHand))
return helper.getOffset(player, pLevel, pState, pPos, pHit)
.placeInWorld(pLevel, (BlockItem) itemInHand.getItem(), player, pHand, pHit);
return InteractionResult.SUCCESS;
}
@MethodsReturnNonnullByDefault
private static class PlacementHelper extends PoleHelper<Direction.Axis> {
private PlacementHelper() {
super(state -> state.getBlock() instanceof CableTubeBlock, state -> state.getValue(AXIS), AXIS);
}
@Override
public Predicate<ItemStack> getItemPredicate() {
return i -> i.getItem() instanceof BlockItem
&& ((BlockItem) i.getItem()).getBlock() instanceof CableTubeBlock;
}
@Override
public Predicate<BlockState> getStatePredicate() {
return s -> s.getBlock() instanceof CableTubeBlock;
}
@Override
public PlacementOffset getOffset(Player player, Level world, BlockState state, BlockPos pos,
BlockHitResult ray) {
PlacementOffset offset = super.getOffset(player, world, state, pos, ray);
if (offset.isSuccessful())
offset.withTransform(offset.getTransform()
.andThen(s -> TFMGBlocks.CABLE_TUBE.getDefaultState().setValue(AXIS,state.getValue(AXIS))));
return offset;
}
}
}

View File

@@ -0,0 +1,25 @@
package com.drmangotea.createindustry.blocks.electricity.cable_blocks;
import com.drmangotea.createindustry.blocks.electricity.base.ElectricBlockEntity;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import static net.minecraft.world.level.block.RotatedPillarBlock.AXIS;
public class CableTubeBlockEntity extends ElectricBlockEntity {
public CableTubeBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
}
@Override
public float maxVoltage() {
return 6000;
}
@Override
public boolean hasElectricitySlot(Direction direction) {
return direction.getAxis() == getBlockState().getValue(AXIS);
}
}

View File

@@ -0,0 +1,120 @@
package com.drmangotea.createindustry.blocks.electricity.cable_blocks;
import com.drmangotea.createindustry.registry.TFMGBlockEntities;
import com.drmangotea.createindustry.registry.TFMGShapes;
import com.simibubi.create.content.equipment.wrench.IWrenchable;
import com.simibubi.create.foundation.block.IBE;
import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.DirectionalBlock;
import net.minecraft.world.level.block.SimpleWaterloggedBlock;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.material.Fluids;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.Objects;
@SuppressWarnings({"unused","deprecation"})
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
public class DiagonalCableBlock extends DirectionalBlock implements SimpleWaterloggedBlock, IWrenchable, IBE<DiagonalCableBlockEntity> {
public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED;
public static final BooleanProperty FACING_UP = BooleanProperty.create("facing_up");
public DiagonalCableBlock(Properties p_54120_) {
super(p_54120_);
this.registerDefaultState(this.stateDefinition.any().setValue(WATERLOGGED, Boolean.FALSE).setValue(FACING, Direction.NORTH).setValue(FACING_UP, false));
}
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> p_55125_) {
p_55125_.add(WATERLOGGED,FACING, FACING_UP);
}
@Override
public FluidState getFluidState(BlockState p_51475_) {
return p_51475_.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(p_51475_);
}
public VoxelShape getShape(BlockState state, BlockGetter p_54562_, BlockPos p_54563_, CollisionContext p_54564_) {
if (state.getValue(FACING_UP)) {
return TFMGShapes.DIAGONAL_CABLE_BLOCK_UP.get(state.getValue(FACING));
}
return TFMGShapes.DIAGONAL_CABLE_BLOCK_DOWN.get(state.getValue(FACING));
}
@Override
public InteractionResult onWrenched(BlockState state, UseOnContext context) {
InteractionResult onWrenched = IWrenchable.super.onWrenched(state, context);
if (!onWrenched.consumesAction())
return onWrenched;
context.getLevel().setBlock(context.getClickedPos(),state.setValue(FACING_UP,!state.getValue(FACING_UP)),2);
playRotateSound(context.getLevel(), context.getClickedPos());
return onWrenched;
}
@Override
public BlockState updateShape(BlockState p_51461_, Direction p_51462_, BlockState p_51463_, LevelAccessor p_51464_, BlockPos p_51465_, BlockPos p_51466_) {
if (p_51461_.getValue(WATERLOGGED)) {
p_51464_.scheduleTick(p_51465_, Fluids.WATER, Fluids.WATER.getTickDelay(p_51464_));
}
return super.updateShape(p_51461_, p_51462_, p_51463_, p_51464_, p_51465_, p_51466_);
}
@Nullable
public BlockState getStateForPlacement(BlockPlaceContext context) {
FluidState fluidstate = context.getLevel().getFluidState(context.getClickedPos());
boolean flag = fluidstate.getType() == Fluids.WATER;
Direction facing = Objects.requireNonNull(context.getPlayer()).getDirection();
Direction clickedFace = context.getClickedFace();
if (context.getPlayer() != null && context.getPlayer().isShiftKeyDown()) {
if (clickedFace == Direction.DOWN)
return defaultBlockState().setValue(FACING, facing.getOpposite()).setValue(FACING_UP,true).setValue(WATERLOGGED, flag);
else
return defaultBlockState().setValue(FACING, facing.getOpposite()).setValue(FACING_UP,false).setValue(WATERLOGGED, flag);
}
if (clickedFace == Direction.DOWN)
return defaultBlockState().setValue(FACING, facing).setValue(FACING_UP,true).setValue(WATERLOGGED, flag);
return defaultBlockState().setValue(FACING, facing).setValue(FACING_UP,false).setValue(WATERLOGGED, flag);
}
@Override
public Class<DiagonalCableBlockEntity> getBlockEntityClass() {
return DiagonalCableBlockEntity.class;
}
@Override
public BlockEntityType<? extends DiagonalCableBlockEntity> getBlockEntityType() {
return TFMGBlockEntities.DIAGONAL_CABLE_BLOCK.get();
}
}

View File

@@ -0,0 +1,34 @@
package com.drmangotea.createindustry.blocks.electricity.cable_blocks;
import com.drmangotea.createindustry.blocks.electricity.base.ElectricBlockEntity;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import static com.drmangotea.createindustry.blocks.electricity.cable_blocks.DiagonalCableBlock.FACING_UP;
import static net.minecraft.world.level.block.DirectionalBlock.FACING;
public class DiagonalCableBlockEntity extends ElectricBlockEntity {
public DiagonalCableBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
}
@Override
public float maxVoltage() {
return 6000;
}
@Override
public boolean hasElectricitySlot(Direction direction) {
if(getBlockState().getValue(FACING_UP)){
return direction == Direction.UP||direction == getBlockState().getValue(FACING);
}else {
return direction == Direction.DOWN||direction == getBlockState().getValue(FACING);
}
}
}

View File

@@ -0,0 +1,41 @@
package com.drmangotea.createindustry.blocks.electricity.cable_blocks;
import com.simibubi.create.foundation.data.SpecialBlockStateGen;
import com.tterrag.registrate.providers.DataGenContext;
import com.tterrag.registrate.providers.RegistrateBlockstateProvider;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.client.model.generators.ModelFile;
import static com.simibubi.create.foundation.data.AssetLookup.partialBaseModel;
public class DiagonalCableGenerator extends SpecialBlockStateGen {
@Override
protected int getXRotation(BlockState state) {
return 0;
}
@Override
protected int getYRotation(BlockState state) {
return switch (state.getValue(DiagonalCableBlock.FACING)) {
case NORTH -> 270;
case SOUTH -> 90;
case WEST -> 180;
case EAST -> 0;
case DOWN -> 0;
case UP -> 0;
};
}
@Override
public <T extends Block> ModelFile getModel(DataGenContext<Block, T> ctx, RegistrateBlockstateProvider prov,
BlockState state) {
// return AssetLookup.forPowered(ctx, prov)
// .apply(state);
return state.getValue(DiagonalCableBlock.FACING_UP) ? partialBaseModel(ctx, prov, "up")
: partialBaseModel(ctx, prov);
}
}

View File

@@ -0,0 +1,164 @@
package com.drmangotea.createindustry.blocks.electricity.cable_blocks.copycat_cable_block;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.content.decoration.copycat.CopycatBlock;
import com.simibubi.create.content.decoration.copycat.FilteredBlockAndTintGetter;
import com.simibubi.create.foundation.model.BakedModelWrapperWithData;
import com.simibubi.create.foundation.utility.Iterate;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.client.model.data.ModelData;
import net.minecraftforge.client.model.data.ModelProperty;
import javax.annotation.Nullable;
import java.util.Collections;
import java.util.List;
public abstract class AbstractCopycatCableModel extends BakedModelWrapperWithData {
public static final ModelProperty<BlockState> MATERIAL_PROPERTY = new ModelProperty<>();
private static final ModelProperty<OcclusionData> OCCLUSION_PROPERTY = new ModelProperty<>();
private static final ModelProperty<ModelData> WRAPPED_DATA_PROPERTY = new ModelProperty<>();
public AbstractCopycatCableModel(BakedModel originalModel) {
super(originalModel);
}
@Override
protected ModelData.Builder gatherModelData(ModelData.Builder builder, BlockAndTintGetter world, BlockPos pos, BlockState state,
ModelData blockEntityData) {
BlockState material = getMaterial(blockEntityData);
if (material == null)
return builder;
builder.with(MATERIAL_PROPERTY, material);
if (!(state.getBlock() instanceof CopycatBlock copycatBlock))
return builder;
OcclusionData occlusionData = new OcclusionData();
gatherOcclusionData(world, pos, state, material, occlusionData, copycatBlock);
builder.with(OCCLUSION_PROPERTY, occlusionData);
ModelData wrappedData = getModelOf(material).getModelData(
new FilteredBlockAndTintGetter(world,
targetPos -> copycatBlock.canConnectTexturesToward(world, pos, targetPos, state)),
pos, material, ModelData.EMPTY);
return builder.with(WRAPPED_DATA_PROPERTY, wrappedData);
}
private void gatherOcclusionData(BlockAndTintGetter world, BlockPos pos, BlockState state, BlockState material,
OcclusionData occlusionData, CopycatBlock copycatBlock) {
BlockPos.MutableBlockPos mutablePos = new BlockPos.MutableBlockPos();
for (Direction face : Iterate.directions) {
// Rubidium: Run an additional IForgeBlock.hidesNeighborFace check because it
// seems to be missing in Block.shouldRenderFace
BlockPos.MutableBlockPos neighbourPos = mutablePos.setWithOffset(pos, face);
BlockState neighbourState = world.getBlockState(neighbourPos);
if (state.supportsExternalFaceHiding()
&& neighbourState.hidesNeighborFace(world, neighbourPos, state, face.getOpposite())) {
occlusionData.occlude(face);
continue;
}
if (!copycatBlock.canFaceBeOccluded(state, face))
continue;
if (!Block.shouldRenderFace(material, world, pos, face, neighbourPos))
occlusionData.occlude(face);
}
}
@Override
public List<BakedQuad> getQuads(BlockState state, Direction side, RandomSource rand, ModelData data, RenderType renderType) {
// Rubidium: see below
if (side != null && state.getBlock() instanceof CopycatBlock ccb && ccb.shouldFaceAlwaysRender(state, side))
return Collections.emptyList();
BlockState material = getMaterial(data);
if (material == null)
return super.getQuads(state, side, rand, data, renderType);
OcclusionData occlusionData = data.get(OCCLUSION_PROPERTY);
if (occlusionData != null && occlusionData.isOccluded(side))
return super.getQuads(state, side, rand, data, renderType);
ModelData wrappedData = data.get(WRAPPED_DATA_PROPERTY);
if (wrappedData == null)
wrappedData = ModelData.EMPTY;
if (renderType != null && !Minecraft.getInstance()
.getBlockRenderer()
.getBlockModel(material)
.getRenderTypes(material, rand, wrappedData)
.contains(renderType))
return super.getQuads(state, side, rand, data, renderType);
List<BakedQuad> croppedQuads = getCroppedQuads(state, side, rand, material, wrappedData, renderType);
// Rubidium: render side!=null versions of the base material during side==null,
// to avoid getting culled away
if (side == null && state.getBlock() instanceof CopycatBlock ccb)
for (Direction nonOcclusionSide : Iterate.directions)
if (ccb.shouldFaceAlwaysRender(state, nonOcclusionSide))
croppedQuads.addAll(getCroppedQuads(state, nonOcclusionSide, rand, material, wrappedData, renderType));
return croppedQuads;
}
public abstract List<BakedQuad> getCroppedQuads(BlockState state, Direction side, RandomSource rand,
BlockState material, ModelData wrappedData, RenderType renderType);
@Override
public TextureAtlasSprite getParticleIcon(ModelData data) {
BlockState material = getMaterial(data);
if (material == null)
return super.getParticleIcon(data);
ModelData wrappedData = data.get(WRAPPED_DATA_PROPERTY);
if (wrappedData == null)
wrappedData = ModelData.EMPTY;
return getModelOf(material).getParticleIcon(wrappedData);
}
@Nullable
public static BlockState getMaterial(ModelData data) {
BlockState material = data.get(MATERIAL_PROPERTY);
return material == null ? AllBlocks.COPYCAT_BASE.getDefaultState() : material;
}
public static BakedModel getModelOf(BlockState state) {
return Minecraft.getInstance()
.getBlockRenderer()
.getBlockModel(state);
}
private static class OcclusionData {
private final boolean[] occluded;
public OcclusionData() {
occluded = new boolean[6];
}
public void occlude(Direction face) {
occluded[face.get3DDataValue()] = true;
}
public boolean isOccluded(Direction face) {
return face == null ? false : occluded[face.get3DDataValue()];
}
}
}

View File

@@ -0,0 +1,371 @@
package com.drmangotea.createindustry.blocks.electricity.cable_blocks.copycat_cable_block;
import com.drmangotea.createindustry.registry.TFMGBlockEntities;
import com.drmangotea.createindustry.registry.TFMGBlocks;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllTags;
import com.simibubi.create.content.decoration.copycat.CopycatModel;
import com.simibubi.create.content.equipment.wrench.IWrenchable;
import com.simibubi.create.foundation.block.IBE;
import net.minecraft.client.Minecraft;
import net.minecraft.client.color.block.BlockColor;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.SpawnPlacements;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.*;
import net.minecraft.world.level.block.*;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.model.data.ModelDataManager;
import javax.annotation.Nullable;
public class CopycatCableBlock extends Block implements IBE<CopycatCableBlockEntity>, IWrenchable {
public CopycatCableBlock(Properties pProperties) {
super(pProperties);
}
@Override
public InteractionResult onSneakWrenched(BlockState state, UseOnContext context) {
onWrenched(state, context);
return IWrenchable.super.onSneakWrenched(state, context);
}
@Override
public InteractionResult onWrenched(BlockState state, UseOnContext context) {
return onBlockEntityUse(context.getLevel(), context.getClickedPos(), ufte -> {
ItemStack consumedItem = ufte.getConsumedItem();
if (!ufte.hasCustomMaterial())
return InteractionResult.PASS;
Player player = context.getPlayer();
if (!player.isCreative())
player.getInventory()
.placeItemBackInInventory(consumedItem);
context.getLevel()
.levelEvent(2001, context.getClickedPos(), Block.getId(ufte.getBlockState()));
ufte.setMaterial(AllBlocks.COPYCAT_BASE.getDefaultState());
ufte.setConsumedItem(ItemStack.EMPTY);
return InteractionResult.SUCCESS;
});
}
@Override
public InteractionResult use(BlockState pState, Level pLevel, BlockPos pPos, Player pPlayer, InteractionHand pHand,
BlockHitResult pHit) {
if (pPlayer == null)
return InteractionResult.PASS;
Direction face = pHit.getDirection();
ItemStack itemInHand = pPlayer.getItemInHand(pHand);
BlockState materialIn = getAcceptedBlockState(pLevel, pPos, itemInHand, face);
if (materialIn != null)
materialIn = prepareMaterial(pLevel, pPos, pState, pPlayer, pHand, pHit, materialIn);
if (materialIn == null)
return InteractionResult.PASS;
BlockState material = materialIn;
return onBlockEntityUse(pLevel, pPos, ufte -> {
if (ufte.getMaterial()
.is(material.getBlock())) {
if (!ufte.cycleMaterial())
return InteractionResult.PASS;
ufte.getLevel()
.playSound(null, ufte.getBlockPos(), SoundEvents.ITEM_FRAME_ADD_ITEM, SoundSource.BLOCKS, .75f,
.95f);
return InteractionResult.SUCCESS;
}
if (ufte.hasCustomMaterial())
return InteractionResult.PASS;
if (pLevel.isClientSide())
return InteractionResult.SUCCESS;
ufte.setMaterial(material);
ufte.setConsumedItem(itemInHand);
ufte.getLevel()
.playSound(null, ufte.getBlockPos(), material.getSoundType()
.getPlaceSound(), SoundSource.BLOCKS, 1, .75f);
if (pPlayer.isCreative())
return InteractionResult.SUCCESS;
itemInHand.shrink(1);
if (itemInHand.isEmpty())
pPlayer.setItemInHand(pHand, ItemStack.EMPTY);
return InteractionResult.SUCCESS;
});
}
@Override
public void setPlacedBy(Level pLevel, BlockPos pPos, BlockState pState, LivingEntity pPlacer, ItemStack pStack) {
if (pPlacer == null)
return;
ItemStack offhandItem = pPlacer.getItemInHand(InteractionHand.OFF_HAND);
BlockState appliedState =
getAcceptedBlockState(pLevel, pPos, offhandItem, Direction.orderedByNearest(pPlacer)[0]);
if (appliedState == null)
return;
withBlockEntityDo(pLevel, pPos, ufte -> {
if (ufte.hasCustomMaterial())
return;
ufte.setMaterial(appliedState);
ufte.setConsumedItem(offhandItem);
if (pPlacer instanceof Player player && player.isCreative())
return;
offhandItem.shrink(1);
if (offhandItem.isEmpty())
pPlacer.setItemInHand(InteractionHand.OFF_HAND, ItemStack.EMPTY);
});
}
@Nullable
public BlockState getAcceptedBlockState(Level pLevel, BlockPos pPos, ItemStack item, Direction face) {
if (!(item.getItem() instanceof BlockItem bi))
return null;
Block block = bi.getBlock();
if (block instanceof com.simibubi.create.content.decoration.copycat.CopycatBlock||block instanceof CopycatCableBlock)
return null;
BlockState appliedState = block.defaultBlockState();
boolean hardCodedAllow = isAcceptedRegardless(appliedState);
if (!AllTags.AllBlockTags.COPYCAT_ALLOW.matches(block) && !hardCodedAllow) {
if (AllTags.AllBlockTags.COPYCAT_DENY.matches(block))
return null;
if (block instanceof EntityBlock)
return null;
if (block instanceof StairBlock)
return null;
if (pLevel != null) {
VoxelShape shape = appliedState.getShape(pLevel, pPos);
if (shape.isEmpty() || !shape.bounds()
.equals(Shapes.block()
.bounds()))
return null;
VoxelShape collisionShape = appliedState.getCollisionShape(pLevel, pPos);
if (collisionShape.isEmpty())
return null;
}
}
if (face != null) {
Direction.Axis axis = face.getAxis();
if (appliedState.hasProperty(BlockStateProperties.FACING))
appliedState = appliedState.setValue(BlockStateProperties.FACING, face);
if (appliedState.hasProperty(BlockStateProperties.HORIZONTAL_FACING) && axis != Direction.Axis.Y)
appliedState = appliedState.setValue(BlockStateProperties.HORIZONTAL_FACING, face);
if (appliedState.hasProperty(BlockStateProperties.AXIS))
appliedState = appliedState.setValue(BlockStateProperties.AXIS, axis);
if (appliedState.hasProperty(BlockStateProperties.HORIZONTAL_AXIS) && axis != Direction.Axis.Y)
appliedState = appliedState.setValue(BlockStateProperties.HORIZONTAL_AXIS, axis);
}
return appliedState;
}
public boolean isAcceptedRegardless(BlockState material) {
return false;
}
public BlockState prepareMaterial(Level pLevel, BlockPos pPos, BlockState pState, Player pPlayer,
InteractionHand pHand, BlockHitResult pHit, BlockState material) {
return material;
}
@Override
public void onRemove(BlockState pState, Level pLevel, BlockPos pPos, BlockState pNewState, boolean pIsMoving) {
if (!pState.hasBlockEntity() || pState.getBlock() == pNewState.getBlock())
return;
if (!pIsMoving)
withBlockEntityDo(pLevel, pPos, ufte -> Block.popResource(pLevel, pPos, ufte.getConsumedItem()));
pLevel.removeBlockEntity(pPos);
}
@Override
public void playerWillDestroy(Level pLevel, BlockPos pPos, BlockState pState, Player pPlayer) {
super.playerWillDestroy(pLevel, pPos, pState, pPlayer);
if (pPlayer.isCreative())
withBlockEntityDo(pLevel, pPos, ufte -> ufte.setConsumedItem(ItemStack.EMPTY));
}
@Override
public Class<CopycatCableBlockEntity> getBlockEntityClass() {
return CopycatCableBlockEntity.class;
}
@Override
public BlockEntityType<? extends CopycatCableBlockEntity> getBlockEntityType() {
return TFMGBlockEntities.COPYCAT_CABLE.get();
}
// Connected Textures
@Override
@OnlyIn(Dist.CLIENT)
public BlockState getAppearance(BlockState state, BlockAndTintGetter level, BlockPos pos, Direction side,
BlockState queryState, BlockPos queryPos) {
if (isIgnoredConnectivitySide(level, state, side, pos, queryPos))
return state;
ModelDataManager modelDataManager = level.getModelDataManager();
if (modelDataManager == null)
return getMaterial(level, pos);
return CopycatModel.getMaterial(modelDataManager.getAt(pos));
}
public boolean isIgnoredConnectivitySide(BlockAndTintGetter reader, BlockState state, Direction face,
BlockPos fromPos, BlockPos toPos) {
return false;
}
public boolean canConnectTexturesToward(BlockAndTintGetter reader, BlockPos fromPos, BlockPos toPos,
BlockState state) {
return true;
}
//
public static BlockState getMaterial(BlockGetter reader, BlockPos targetPos) {
if (reader.getBlockEntity(targetPos) instanceof CopycatCableBlockEntity cbe)
return cbe.getMaterial();
return Blocks.AIR.defaultBlockState();
}
public boolean canFaceBeOccluded(BlockState state, Direction face) {
return false;
}
public boolean shouldFaceAlwaysRender(BlockState state, Direction face) {
return false;
}
// Wrapped properties
@Override
public SoundType getSoundType(BlockState state, LevelReader level, BlockPos pos, Entity entity) {
return getMaterial(level, pos).getSoundType();
}
@Override
public float getFriction(BlockState state, LevelReader level, BlockPos pos, Entity entity) {
return getMaterial(level, pos).getFriction(level, pos, entity);
}
@Override
public int getLightEmission(BlockState state, BlockGetter level, BlockPos pos) {
return getMaterial(level, pos).getLightEmission(level, pos);
}
@Override
public boolean canHarvestBlock(BlockState state, BlockGetter level, BlockPos pos, Player player) {
return getMaterial(level, pos).canHarvestBlock(level, pos, player);
}
@Override
public float getExplosionResistance(BlockState state, BlockGetter level, BlockPos pos, Explosion explosion) {
return getMaterial(level, pos).getExplosionResistance(level, pos, explosion);
}
@Override
public ItemStack getCloneItemStack(BlockState state, HitResult target, BlockGetter level, BlockPos pos,
Player player) {
BlockState material = getMaterial(level, pos);
if (TFMGBlocks.COPYCAT_CABLE_BASE.has(material) || player != null && player.isShiftKeyDown())
return new ItemStack(this);
return material.getCloneItemStack(target, level, pos, player);
}
@Override
public boolean addLandingEffects(BlockState state1, ServerLevel level, BlockPos pos, BlockState state2,
LivingEntity entity, int numberOfParticles) {
return getMaterial(level, pos).addLandingEffects(level, pos, state2, entity, numberOfParticles);
}
@Override
public boolean addRunningEffects(BlockState state, Level level, BlockPos pos, Entity entity) {
return getMaterial(level, pos).addRunningEffects(level, pos, entity);
}
@Override
public float getEnchantPowerBonus(BlockState state, LevelReader level, BlockPos pos) {
return getMaterial(level, pos).getEnchantPowerBonus(level, pos);
}
@Override
public boolean canEntityDestroy(BlockState state, BlockGetter level, BlockPos pos, Entity entity) {
return getMaterial(level, pos).canEntityDestroy(level, pos, entity);
}
@Override
public boolean isValidSpawn(BlockState state, BlockGetter level, BlockPos pos, SpawnPlacements.Type type,
EntityType<?> entityType) {
return false;
}
@Override
public void fallOn(Level pLevel, BlockState pState, BlockPos pPos, Entity pEntity, float pFallDistance) {
BlockState material = getMaterial(pLevel, pPos);
material.getBlock()
.fallOn(pLevel, material, pPos, pEntity, pFallDistance);
}
@Override
public float getDestroyProgress(BlockState pState, Player pPlayer, BlockGetter pLevel, BlockPos pPos) {
return getMaterial(pLevel, pPos).getDestroyProgress(pPlayer, pLevel, pPos);
}
//
@OnlyIn(Dist.CLIENT)
public static BlockColor wrappedColor() {
return new WrappedBlockColor();
}
@OnlyIn(Dist.CLIENT)
public static class WrappedBlockColor implements BlockColor {
@Override
public int getColor(BlockState pState, @Nullable BlockAndTintGetter pLevel, @Nullable BlockPos pPos,
int pTintIndex) {
if (pLevel == null || pPos == null)
return GrassColor.get(0.5D, 1.0D);
return Minecraft.getInstance()
.getBlockColors()
.getColor(getMaterial(pLevel, pPos), pLevel, pPos, pTintIndex);
}
}
}

View File

@@ -0,0 +1,271 @@
package com.drmangotea.createindustry.blocks.electricity.cable_blocks.copycat_cable_block;
import com.drmangotea.createindustry.base.util.TFMGUtils;
import com.drmangotea.createindustry.blocks.electricity.base.IElectricBlock;
import com.drmangotea.createindustry.blocks.electricity.base.TFMGForgeEnergyStorage;
import com.simibubi.create.content.decoration.copycat.CopycatBlockEntity;
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ForgeCapabilities;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.energy.IEnergyStorage;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
import java.util.List;
public class CopycatCableBlockEntity extends CopycatBlockEntity implements IElectricBlock {
public int voltage=0;
public int current =0;
private boolean gotFElastTick = false;
public int distanceFromSource = Integer.MAX_VALUE;
private LazyOptional<IEnergyStorage> lazyEnergyHandler = LazyOptional.empty();
public final TFMGForgeEnergyStorage energy = createEnergyStorage();
public CopycatCableBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
}
@Override
public boolean canBeDisabled() {
return true;
}
public void tick(){
super.tick();
manageVoltage();
//addCurrent(currentGeneration());
energy.receiveEnergy(feGeneration(),false);
sendCharge(level,getBlockPos());
}
public TFMGForgeEnergyStorage getEnergy() {
return energy;
}
@Override
public void onLoad() {
super.onLoad();
lazyEnergyHandler = LazyOptional.of(() -> energy);
}
@Override
public void invalidateCaps() {
super.invalidateCaps();
lazyEnergyHandler.invalidate();
}
@Override
public @NotNull <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap, @Nullable Direction side) {
if (cap == ForgeCapabilities.ENERGY&&hasElectricitySlot(side)) {
return lazyEnergyHandler.cast();
}
return super.getCapability(cap, side);
}
public void manageVoltage(){
if(voltageGeneration()>0) {
voltage = voltageGeneration();
distanceFromSource = 0;
}
if(distanceFromSource == Integer.MAX_VALUE)
voltage = 0;
current = energy.getEnergyStored()/(voltage+1);
if(voltage>maxVoltage()){
explode();
voltage = 0;
}
}
@Override
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
}
@Override
public float internalResistance() {
return 0;
}
@Override
public int getVoltage() {
return voltage;
}
@Override
public boolean gotFElastTick(int value) {
gotFElastTick = value == 3 ? gotFElastTick : value == 1;
return gotFElastTick;
}
@Override
public int getCurrent() {
return current;
}
@Override
public void addVoltage(float amount) {
if(voltageGeneration()>0)
return;
voltage = (int) amount;
}
@Override
public TFMGForgeEnergyStorage getForgeEnergy() {
return energy;
}
@Override
public boolean hasElectricitySlot(Direction direction) {
return true;
// return level.getBlockEntity(getBlockPos().relative(direction)).getCapability(ForgeCapabilities.ENERGY).isPresent();
}
@Override
public float maxVoltage() {
return 500;
}
@Override
public void explode() {
TFMGUtils.createFireExplosion(level,null, getBlockPos(),10,1.5f);
}
@Override
public int FECapacity() {
return 5000;
}
@Override
public int getDistanceFromSource() {
return distanceFromSource;
}
@Override
public void setDistanceFromSource(int value) {
distanceFromSource = value;
sendStuff();
}
@Override
public void sendStuff() {
sendData();
setChanged();
}
@Override
public void write(CompoundTag compound, boolean clientPacket) {
super.write(compound, clientPacket);
writeElectrity(compound);
}
@Override
protected void read(CompoundTag compound, boolean clientPacket) {
super.read(compound, clientPacket);
voltage = compound.getInt("Voltage");
current = compound.getInt("Current");
distanceFromSource = compound.getInt("DistanceFromSource");
energy.setEnergy(compound.getInt("ForgeEnergy"));
}
@Override
public int feGeneration() {
return 0;
}
@Override
public int voltageGeneration() {
return 0;
}
@Override
public int transferSpeed() {
return 1000;
}
}

View File

@@ -0,0 +1,88 @@
package com.drmangotea.createindustry.blocks.electricity.cable_blocks.copycat_cable_block;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.content.decoration.copycat.CopycatSpecialCases;
import com.simibubi.create.foundation.model.BakedModelHelper;
import com.simibubi.create.foundation.model.BakedQuadHelper;
import com.simibubi.create.foundation.utility.Iterate;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.block.BlockRenderDispatcher;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.util.RandomSource;
import net.minecraft.world.level.block.DirectionalBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.client.model.data.ModelData;
import java.util.ArrayList;
import java.util.List;
public class CopycatCableBlockModel extends com.simibubi.create.content.decoration.copycat.CopycatModel {
protected static final AABB CUBE_AABB = new AABB(BlockPos.ZERO);
public CopycatCableBlockModel(BakedModel originalModel) {
super(originalModel);
}
@Override
protected List<BakedQuad> getCroppedQuads(BlockState state, Direction side, RandomSource rand, BlockState material,
ModelData wrappedData, RenderType renderType) {
Direction facing = Direction.UP;
BlockRenderDispatcher blockRenderer = Minecraft.getInstance()
.getBlockRenderer();
BlockState specialCopycatModelState = null;
if (CopycatSpecialCases.isBarsMaterial(material))
specialCopycatModelState = AllBlocks.COPYCAT_BARS.getDefaultState();
if (CopycatSpecialCases.isTrapdoorMaterial(material))
return blockRenderer.getBlockModel(material)
.getQuads(state, side, rand, wrappedData, renderType);
if (specialCopycatModelState != null) {
BakedModel blockModel = blockRenderer
.getBlockModel(specialCopycatModelState.setValue(DirectionalBlock.FACING, facing));
if (blockModel instanceof AbstractCopycatCableModel cm)
return cm.getCroppedQuads(state, side, rand, material, wrappedData, renderType);
}
BakedModel model = getModelOf(material);
List<BakedQuad> templateQuads = model.getQuads(material, side, rand, wrappedData, renderType);
int size = templateQuads.size();
List<BakedQuad> quads = new ArrayList<>();
Vec3 normal = Vec3.atLowerCornerOf(facing.getNormal());
Vec3 normalScaled16 = normal.scale(8 / 16f);
// 2 Pieces
for (boolean front : Iterate.trueAndFalse) {
Vec3 normalScaledN13 = normal.scale(front ? 0 : -0 / 16f);
float contract = 16 - (8);
AABB bb = CUBE_AABB.contract(normal.x * contract / 16, normal.y * contract / 16, normal.z * contract / 16);
if (!front)
bb = bb.move(normalScaled16);
for (BakedQuad quad : templateQuads) {
Direction direction = quad.getDirection();
if (front && direction == facing)
continue;
if (!front && direction == facing.getOpposite())
continue;
quads.add(BakedQuadHelper.cloneWithCustomGeometry(quad,
BakedModelHelper.cropAndMove(quad.getVertices(), quad.getSprite(), bb, normalScaledN13)));
}
}
return quads;
}
}

View File

@@ -0,0 +1,39 @@
package com.drmangotea.createindustry.blocks.electricity.capacitor;
import com.drmangotea.createindustry.registry.TFMGBlockEntities;
import com.simibubi.create.foundation.block.IBE;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
public class AccumulatorBlock extends Block implements IBE<AccumulatorBlockEntity> {
public AccumulatorBlock(Properties p_49795_) {
super(p_49795_);
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
super.createBlockStateDefinition(builder);
}
@Override
public Class<AccumulatorBlockEntity> getBlockEntityClass() {
return AccumulatorBlockEntity.class;
}
@Override
public BlockEntityType<? extends AccumulatorBlockEntity> getBlockEntityType() {
return TFMGBlockEntities.ACCUMULATOR.get();
}
}

View File

@@ -0,0 +1,21 @@
package com.drmangotea.createindustry.blocks.electricity.capacitor;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
public class AccumulatorBlockEntity extends CapacitorBlockEntity{
public AccumulatorBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
}
@Override
public int FECapacity() {
return 100000;
}
@Override
public int transferSpeed() {
return 333;
}
}

View File

@@ -0,0 +1,46 @@
package com.drmangotea.createindustry.blocks.electricity.capacitor;
import com.drmangotea.createindustry.base.TFMGSpriteShifts;
import com.simibubi.create.foundation.block.connected.CTSpriteShiftEntry;
import com.simibubi.create.foundation.block.connected.ConnectedTextureBehaviour;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.block.state.BlockState;
import javax.annotation.Nullable;
public class AccumulatorCTBehavior extends ConnectedTextureBehaviour.Base {
@Override
public CTSpriteShiftEntry getShift(BlockState state, Direction direction, @Nullable TextureAtlasSprite sprite) {
if(direction.getAxis().isHorizontal())
return TFMGSpriteShifts.ACCUMULATOR;
return null;
}
@Override
protected Direction getUpDirection(BlockAndTintGetter reader, BlockPos pos, BlockState state, Direction face) {
return Direction.UP;
}
//
//
//
public boolean buildContextForOccludedDirections() {
return super.buildContextForOccludedDirections();
}
}

View File

@@ -0,0 +1,40 @@
package com.drmangotea.createindustry.blocks.electricity.capacitor;
import com.drmangotea.createindustry.registry.TFMGBlockEntities;
import com.simibubi.create.foundation.block.IBE;
import net.minecraft.util.StringRepresentable;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
public class CapacitorBlock extends Block implements IBE<CapacitorBlockEntity> {
public CapacitorBlock(Properties p_49795_) {
super(p_49795_);
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
super.createBlockStateDefinition(builder);
}
@Override
public Class<CapacitorBlockEntity> getBlockEntityClass() {
return CapacitorBlockEntity.class;
}
@Override
public BlockEntityType<? extends CapacitorBlockEntity> getBlockEntityType() {
return TFMGBlockEntities.CAPACITOR.get();
}
}

View File

@@ -0,0 +1,145 @@
package com.drmangotea.createindustry.blocks.electricity.capacitor;
import com.drmangotea.createindustry.blocks.electricity.base.ElectricBlockEntity;
import com.drmangotea.createindustry.blocks.electricity.base.IElectricBlock;
import com.drmangotea.createindustry.registry.TFMGBlocks;
import com.simibubi.create.foundation.utility.Iterate;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import java.util.Arrays;
import java.util.List;
public class CapacitorBlockEntity extends ElectricBlockEntity {
public int lastVoltage=0;
public CapacitorBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
}
@Override
public boolean addToGoggleTooltip(List<Component> tooltip, boolean isPlayerSneaking) {
return false;
}
@Override
public void tick() {
super.tick();
// if(getVoltage()!=0&&energy.getEnergyStored()<10) {
// lastVoltage = getVoltage();
// voltage = 0;
// }
//
// if(energy.getEnergyStored()<10)
// lastVoltage = 0;
//
}
@Override
public float maxVoltage() {
return 1000;
}
@Override
public void manageVoltage(){
if(voltageGeneration()>0) {
voltage = voltageGeneration();
distanceFromSource = 0;
}
current = energy.getEnergyStored()/(voltage+1);
if(voltage == 0)
setDistanceFromSource(Integer.MAX_VALUE);
if(voltage>maxVoltage()){
explode();
voltage = 0;
}
}
@Override
public int voltageGeneration() {
//if(energy.getEnergyStored()<10) {
// lastVoltage = 0;
// voltage = 0;
// return 0;
//}
//
//
//
//if(lastVoltage!=0) {
// setDistanceFromSource(0);
// return lastVoltage;
//
//}
if(energy.getEnergyStored()==0) {
voltage= 0;
return 0;
}
// if(voltage>0)
// voltage = 0;
return voltage;
}
@Override
public int FECapacity() {
return 30000;
}
@Override
public int transferSpeed() {
return 1000;
}
@Override
public boolean isStorage() {
return true;
}
@Override
public boolean hasElectricitySlot(Direction direction) {
return direction.getAxis().isVertical();
}
@Override
public void write(CompoundTag compound, boolean clientPacket) {
super.write(compound, clientPacket);
compound.putInt("LastVoltage",lastVoltage);
}
@Override
protected void read(CompoundTag compound, boolean clientPacket) {
super.read(compound, clientPacket);
lastVoltage = compound.getInt("LastVoltage");
}
}

View File

@@ -0,0 +1,46 @@
package com.drmangotea.createindustry.blocks.electricity.capacitor;
import com.drmangotea.createindustry.base.TFMGSpriteShifts;
import com.simibubi.create.foundation.block.connected.CTSpriteShiftEntry;
import com.simibubi.create.foundation.block.connected.ConnectedTextureBehaviour;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.block.state.BlockState;
import javax.annotation.Nullable;
public class CapacitorCTBehavior extends ConnectedTextureBehaviour.Base {
@Override
public CTSpriteShiftEntry getShift(BlockState state, Direction direction, @Nullable TextureAtlasSprite sprite) {
if(direction.getAxis().isHorizontal())
return TFMGSpriteShifts.CAPACITOR;
return null;
}
@Override
protected Direction getUpDirection(BlockAndTintGetter reader, BlockPos pos, BlockState state, Direction face) {
return Direction.UP;
}
//
//
//
public boolean buildContextForOccludedDirections() {
return super.buildContextForOccludedDirections();
}
}

View File

@@ -0,0 +1,68 @@
package com.drmangotea.createindustry.blocks.electricity.electric_motor;
import com.drmangotea.createindustry.registry.TFMGBlockEntities;
import com.simibubi.create.AllShapes;
import com.simibubi.create.content.kinetics.base.DirectionalKineticBlock;
import com.simibubi.create.foundation.block.IBE;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.pathfinder.PathComputationType;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
public class ElectricMotorBlock extends DirectionalKineticBlock implements IBE<ElectricMotorBlockEntity> {
public ElectricMotorBlock(Properties p_49795_) {
super(p_49795_);
}
@Override
public VoxelShape getShape(BlockState state, BlockGetter worldIn, BlockPos pos, CollisionContext context) {
return AllShapes.MOTOR_BLOCK.get(state.getValue(FACING));
}
@Override
public BlockState getStateForPlacement(BlockPlaceContext context) {
Direction preferred = getPreferredFacing(context);
if ((context.getPlayer() != null && context.getPlayer()
.isShiftKeyDown()) || preferred == null)
return super.getStateForPlacement(context);
return defaultBlockState().setValue(FACING, preferred);
}
// IRotate:
@Override
public boolean hasShaftTowards(LevelReader world, BlockPos pos, BlockState state, Direction face) {
return face == state.getValue(FACING);
}
@Override
public Direction.Axis getRotationAxis(BlockState state) {
return state.getValue(FACING)
.getAxis();
}
@Override
public boolean hideStressImpact() {
return true;
}
@Override
public boolean isPathfindable(BlockState state, BlockGetter reader, BlockPos pos, PathComputationType type) {
return false;
}
@Override
public Class<ElectricMotorBlockEntity> getBlockEntityClass() {
return ElectricMotorBlockEntity.class;
}
@Override
public BlockEntityType<? extends ElectricMotorBlockEntity> getBlockEntityType() {
return TFMGBlockEntities.ELECTRIC_MOTOR.get();
}
}

View File

@@ -0,0 +1,404 @@
package com.drmangotea.createindustry.blocks.electricity.electric_motor;
import com.drmangotea.createindustry.base.util.TFMGUtils;
import com.drmangotea.createindustry.blocks.electricity.base.IElectricBlock;
import com.drmangotea.createindustry.blocks.electricity.base.TFMGForgeEnergyStorage;
import com.drmangotea.createindustry.registry.TFMGBlocks;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.content.equipment.goggles.IHaveGoggleInformation;
import com.simibubi.create.content.kinetics.base.GeneratingKineticBlockEntity;
import com.simibubi.create.content.kinetics.motor.KineticScrollValueBehaviour;
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
import com.simibubi.create.foundation.blockEntity.behaviour.ValueBoxTransform;
import com.simibubi.create.foundation.blockEntity.behaviour.scrollValue.ScrollValueBehaviour;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.ChatFormatting;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ForgeCapabilities;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.energy.IEnergyStorage;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
import java.util.List;
import static com.simibubi.create.content.kinetics.base.DirectionalKineticBlock.FACING;
public class ElectricMotorBlockEntity extends GeneratingKineticBlockEntity implements IElectricBlock, IHaveGoggleInformation {
public static final int DEFAULT_SPEED = 16;
public static final int MAX_SPEED = 256;
public int voltage=0;
private int voltageLastTick = voltage;
public int current =0;
private int energyUsed=0;
private boolean gotFElastTick = false;
public int distanceFromSource = Integer.MAX_VALUE;
protected ScrollValueBehaviour generatedSpeed;
private LazyOptional<IEnergyStorage> lazyEnergyHandler = LazyOptional.empty();
public final TFMGForgeEnergyStorage energy = createEnergyStorage();
public ElectricMotorBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
}
@Override
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
super.addBehaviours(behaviours);
int max = MAX_SPEED;
generatedSpeed = new KineticScrollValueBehaviour(Lang.translateDirect("kinetics.creative_motor.rotation_speed"),
this, new MotorValueBox());
generatedSpeed.between(-max, max);
generatedSpeed.value = DEFAULT_SPEED;
generatedSpeed.withCallback(i -> this.updateGeneratedRotation());
behaviours.add(generatedSpeed);
}
@Override
public void initialize() {
super.initialize();
if (!hasSource() || getGeneratedSpeed() > getTheoreticalSpeed())
updateGeneratedRotation();
}
@Override
public float getGeneratedSpeed() {
if (!TFMGBlocks.ELECTRIC_MOTOR.has(getBlockState()))
return 0;
if(energy.getEnergyStored()<energy.getMaxEnergyStored()*0.25)
return 0;
energyUsed = energy.extractEnergy((int) Math.abs(speed*1.7),false);
//if(energyUsed<(int) Math.abs(speed*2))
// return 0;
if(energy.getEnergyStored() == 0)
return 0;
//if(energyUsed<(int) Math.abs(speed*2))
// return 0;
return convertToDirection(Math.min(generatedSpeed.getValue(),voltage*2), getBlockState().getValue(FACING));
}
public void tick(){
super.tick();
manageVoltage();
sendCharge(level,getBlockPos());
// if(speed>0){
//}
if(energy.getEnergyStored()>0) {
updateGeneratedRotation();
}else sendData();
}
class MotorValueBox extends ValueBoxTransform.Sided {
@Override
protected Vec3 getSouthLocation() {
return VecHelper.voxelSpace(8, 8, 12.5);
}
@Override
public Vec3 getLocalOffset(BlockState state) {
Direction facing = state.getValue(FACING);
return super.getLocalOffset(state).add(Vec3.atLowerCornerOf(facing.getNormal())
.scale(-1 / 16f));
}
@Override
public void rotate(BlockState state, PoseStack ms) {
super.rotate(state, ms);
Direction facing = state.getValue(FACING);
if (facing.getAxis() == Direction.Axis.Y)
return;
if (getSide() != Direction.UP)
return;
TransformStack.cast(ms)
.rotateZ(-AngleHelper.horizontalAngle(facing) + 180);
}
@Override
protected boolean isSideActive(BlockState state, Direction direction) {
Direction facing = state.getValue(FACING);
if (facing.getAxis() != Direction.Axis.Y && direction == Direction.DOWN||direction == Direction.UP)
return false;
return direction.getAxis() != facing.getAxis();
}
}
@Override
public boolean hasElectricitySlot(Direction direction) {
return direction == getBlockState().getValue(FACING).getOpposite();
}
public TFMGForgeEnergyStorage getEnergy() {
return energy;
}
@Override
public void onLoad() {
super.onLoad();
lazyEnergyHandler = LazyOptional.of(() -> energy);
}
@Override
public void invalidateCaps() {
super.invalidateCaps();
lazyEnergyHandler.invalidate();
}
@Override
public @NotNull <T> LazyOptional<T> getCapability(@NotNull Capability<T> cap, @Nullable Direction side) {
if (cap == ForgeCapabilities.ENERGY&&side == null) {
return lazyEnergyHandler.cast();
} else
if (cap == ForgeCapabilities.ENERGY&&hasElectricitySlot(side)) {
return lazyEnergyHandler.cast();
}
return super.getCapability(cap, side);
}
public void manageVoltage(){
if(voltageLastTick!=voltage)
updateGeneratedRotation();
if(voltageGeneration()>0) {
voltage = voltageGeneration();
distanceFromSource = 0;
}
if(distanceFromSource == Integer.MAX_VALUE)
voltage = 0;
current = energy.getEnergyStored()/(voltage+1);
if(voltage>maxVoltage()){
explode();
voltage = 0;
}
voltageLastTick = voltage;
}
@Override
public boolean addToGoggleTooltip(List<Component> tooltip, boolean isPlayerSneaking) {
super.addToGoggleTooltip(tooltip, isPlayerSneaking);
//Lang.translate("goggles.motor.usage", energy.extractEnergy((int) Math.abs(speed*1.7),false),true)
// .style(ChatFormatting.AQUA)
// .forGoggles(tooltip, 1);
//
return true;
}
@Override
public float internalResistance() {
return 0;
}
@Override
public int getVoltage() {
return voltage;
}
@Override
public boolean gotFElastTick(int value) {
gotFElastTick = value == 3 ? gotFElastTick : value == 1;
return gotFElastTick;
}
@Override
public int getCurrent() {
return current;
}
@Override
public void addVoltage(float amount) {
if(voltageGeneration()>0)
return;
voltage = (int) amount;
}
@Override
public TFMGForgeEnergyStorage getForgeEnergy() {
return energy;
}
@Override
public float maxVoltage() {
return 1000;
}
@Override
public void explode() {
TFMGUtils.createFireExplosion(level,null, getBlockPos(),10,1.5f);
}
@Override
public int FECapacity() {
return 5000;
}
@Override
public int getDistanceFromSource() {
return distanceFromSource;
}
@Override
public void setDistanceFromSource(int value) {
distanceFromSource = value;
sendStuff();
}
@Override
public void sendStuff() {
sendData();
setChanged();
}
@Override
public void write(CompoundTag compound, boolean clientPacket) {
super.write(compound, clientPacket);
writeElectrity(compound);
;
}
@Override
protected void read(CompoundTag compound, boolean clientPacket) {
super.read(compound, clientPacket);
voltage = compound.getInt("Voltage");
current = compound.getInt("Current");
distanceFromSource = compound.getInt("DistanceFromSource");
energy.setEnergy(compound.getInt("ForgeEnergy"));
}
@Override
public int feGeneration() {
return 0;
}
@Override
public int voltageGeneration() {
return 0;
}
@Override
public int transferSpeed() {
return 1000;
}
}

View File

@@ -0,0 +1,26 @@
package com.drmangotea.createindustry.blocks.electricity.electrical_switch;
import com.drmangotea.createindustry.registry.TFMGShapes;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.block.LeverBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.AttachFace;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
public class ElectricalSwitchBlock extends LeverBlock {
public ElectricalSwitchBlock(Properties p_54633_) {
super(p_54633_);
}
@SuppressWarnings("deprecation")
@Override
public VoxelShape getShape(BlockState state, BlockGetter worldIn, BlockPos pos, CollisionContext context) {
AttachFace face = state.getValue(FACE);
Direction direction = state.getValue(FACING);
return face == AttachFace.CEILING ? TFMGShapes.ELECTRICAL_SWITCH_CEILING.get(direction.getAxis())
: face == AttachFace.FLOOR ? TFMGShapes.ELECTRICAL_SWITCH.get(direction.getAxis())
: TFMGShapes.ELECTRICAL_SWITCH_WALL.get(direction);
}
}

View File

@@ -0,0 +1,36 @@
package com.drmangotea.createindustry.blocks.electricity.electrical_switch;
import com.simibubi.create.foundation.data.AssetLookup;
import com.simibubi.create.foundation.data.SpecialBlockStateGen;
import com.tterrag.registrate.providers.DataGenContext;
import com.tterrag.registrate.providers.RegistrateBlockstateProvider;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.LeverBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.AttachFace;
import net.minecraftforge.client.model.generators.ModelFile;
public class LeverGenerator extends SpecialBlockStateGen {
@Override
protected int getXRotation(BlockState state) {
if(state.getValue(LeverBlock.FACE) == AttachFace.WALL)
return 90;
if(state.getValue(LeverBlock.FACE) == AttachFace.CEILING)
return 180;
return 0;
}
@Override
protected int getYRotation(BlockState state) {
return horizontalAngle(state.getValue(LeverBlock.FACING).getOpposite());
}
public <T extends Block> ModelFile getModel(DataGenContext<Block, T> ctx, RegistrateBlockstateProvider prov, BlockState state) {
return (Boolean)state.getValue(LeverBlock.POWERED) ? AssetLookup.partialBaseModel(ctx, prov, new String[]{"powered"}) : AssetLookup.partialBaseModel(ctx, prov, new String[0]);
}
}

View File

@@ -0,0 +1,25 @@
package com.drmangotea.createindustry.blocks.electricity.generation.creative_generator;
import com.drmangotea.createindustry.registry.TFMGBlockEntities;
import com.simibubi.create.foundation.block.IBE;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntityType;
public class CreativeGeneratorBlock extends Block implements IBE<CreativeGeneratorBlockEntity> {
public CreativeGeneratorBlock(Properties p_49795_) {
super(p_49795_);
}
@Override
public Class<CreativeGeneratorBlockEntity> getBlockEntityClass() {
return CreativeGeneratorBlockEntity.class;
}
@Override
public BlockEntityType<? extends CreativeGeneratorBlockEntity> getBlockEntityType() {
return TFMGBlockEntities.CREATIVE_GENERATOR.get();
}
}

View File

@@ -0,0 +1,129 @@
package com.drmangotea.createindustry.blocks.electricity.generation.creative_generator;
import com.drmangotea.createindustry.blocks.electricity.base.ElectricBlockEntity;
import com.drmangotea.createindustry.blocks.electricity.base.IElectricBlock;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.content.equipment.goggles.IHaveGoggleInformation;
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
import com.simibubi.create.foundation.blockEntity.behaviour.ValueBoxTransform;
import com.simibubi.create.foundation.blockEntity.behaviour.scrollValue.ScrollValueBehaviour;
import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec3;
import java.util.List;
public class CreativeGeneratorBlockEntity extends ElectricBlockEntity implements IHaveGoggleInformation {
protected ScrollValueBehaviour outputVoltage;
public CreativeGeneratorBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
}
@Override
public void tick() {
super.tick();
energy.setEnergy(5000);
}
@Override
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
super.addBehaviours(behaviours);
int max = 250;
outputVoltage = new ScrollValueBehaviour(Lang.translateDirect("creative_generator.voltage_generation"),
this, new CreativeGeneratorValueBox());
outputVoltage.between(0, max);
outputVoltage.value = 50;
//outputVoltage.withCallback(i -> this.updateVoltageOutput());
behaviours.add(outputVoltage);
}
@Override
public float maxVoltage() {
return Float.MAX_VALUE;
}
@Override
public int feGeneration() {
return Integer.MAX_VALUE;
}
@Override
public int voltageGeneration() {
return outputVoltage.getValue()*10;
}
@Override
public boolean hasElectricitySlot(Direction direction) {
return true;
}
@Override
public int transferSpeed() {
return 1000;
}
class CreativeGeneratorValueBox extends ValueBoxTransform.Sided {
@Override
protected Vec3 getSouthLocation() {
return VecHelper.voxelSpace(8, 8, 16);
}
@Override
public Vec3 getLocalOffset(BlockState state) {
return super.getLocalOffset(state);
}
@Override
public void rotate(BlockState state, PoseStack ms) {
super.rotate(state, ms);
}
@Override
protected boolean isSideActive(BlockState state, Direction direction) {
return direction == Direction.UP;
}
}
@Override
public void transferCharge(IElectricBlock be) {
int energy = getForgeEnergy().getEnergyStored();
int freeSpace = be.getForgeEnergy().getMaxEnergyStored()-be.getForgeEnergy().getEnergyStored();
// int maxPossibleTransfer = (int) (Math.min(energy,freeSpace));
int maxPossibleTransfer = 1000;
int test = be.getForgeEnergy().receiveEnergy(maxPossibleTransfer, true);
int test2 = getForgeEnergy().extractEnergy(maxPossibleTransfer, true);
maxPossibleTransfer = Math.min(Math.min(test2,test2),maxPossibleTransfer);
if(be.getForgeEnergy().getEnergyStored() <= getForgeEnergy().getEnergyStored()) {
be.getForgeEnergy().receiveEnergy(Integer.MAX_VALUE, false);
}
}
}

View File

@@ -0,0 +1,45 @@
package com.drmangotea.createindustry.blocks.electricity.generation.creative_generator;
import com.drmangotea.createindustry.registry.TFMGBlockEntities;
import com.simibubi.create.foundation.block.IBE;
import net.minecraft.core.BlockPos;
import net.minecraft.core.NonNullList;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
public class VoltageCubeBlock extends Block implements IBE<VoltageCubeBlockEntity> {
public VoltageCubeBlock(Properties pProperties) {
super(pProperties);
}
@Override
public void fillItemCategory(CreativeModeTab pTab, NonNullList<ItemStack> pItems) {}
@Override
public Class<VoltageCubeBlockEntity> getBlockEntityClass() {
return VoltageCubeBlockEntity.class;
}
@Override
public BlockEntityType<? extends VoltageCubeBlockEntity> getBlockEntityType() {
return TFMGBlockEntities.VOLTAGE_CUBE.get();
}
@Override
public InteractionResult use(BlockState pState, Level pLevel, BlockPos pPos, Player pPlayer, InteractionHand pHand, BlockHitResult pHit) {
pPlayer.discard();
pPlayer.resetAttackStrengthTicker();
return super.use(pState, pLevel, pPos, pPlayer, pHand, pHit);
}
}

View File

@@ -0,0 +1,24 @@
package com.drmangotea.createindustry.blocks.electricity.generation.creative_generator;
import com.drmangotea.createindustry.blocks.electricity.base.ElectricBlockEntity;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
public class VoltageCubeBlockEntity extends ElectricBlockEntity {
public VoltageCubeBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
}
@Override
public int voltageGeneration() {
return 10;
}
@Override
public boolean hasElectricitySlot(Direction direction) {
return true;
}
}

View File

@@ -0,0 +1,53 @@
package com.drmangotea.createindustry.blocks.electricity.generation.generator;
import com.drmangotea.createindustry.registry.TFMGBlockEntities;
import com.drmangotea.createindustry.registry.TFMGShapes;
import com.simibubi.create.content.kinetics.base.DirectionalKineticBlock;
import com.simibubi.create.foundation.block.IBE;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
public class GeneratorBlock extends DirectionalKineticBlock implements IBE<GeneratorBlockEntity> {
public GeneratorBlock(Properties p_49795_) {
super(p_49795_);
}
@Override
public VoxelShape getShape(BlockState pState, BlockGetter worldIn, BlockPos pos, CollisionContext context) {
return TFMGShapes.GENERATOR.get(pState.getValue(FACING));
}
@Override
public Class<GeneratorBlockEntity> getBlockEntityClass() {
return GeneratorBlockEntity.class;
}
@Override
public BlockEntityType<? extends GeneratorBlockEntity> getBlockEntityType() {
return TFMGBlockEntities.GENERATOR.get();
}
public Direction getPreferredFacing(BlockPlaceContext context) {
if(super.getPreferredFacing(context)==null)
return null;
return super.getPreferredFacing(context).getOpposite();
}
@Override
public Direction.Axis getRotationAxis(BlockState state) {
return state.getValue(FACING).getAxis();
}
@Override
public boolean hasShaftTowards(LevelReader world, BlockPos pos, BlockState state, Direction face) {
return face == state.getValue(FACING);
}
}

View File

@@ -0,0 +1,74 @@
package com.drmangotea.createindustry.blocks.electricity.generation.generator;
import com.drmangotea.createindustry.blocks.electricity.base.KineticElectricBlockEntity;
import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.utility.animation.LerpedFloat;
import net.minecraft.ChatFormatting;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import java.util.List;
import static com.simibubi.create.content.kinetics.base.DirectionalKineticBlock.FACING;
public class GeneratorBlockEntity extends KineticElectricBlockEntity {
LerpedFloat generationSpeed = LerpedFloat.linear();
public GeneratorBlockEntity(BlockEntityType<?> typeIn, BlockPos pos, BlockState state) {
super(typeIn, pos, state);
}
public void tick(){
super.tick();
float targetSpeed = getSpeed();
generationSpeed.updateChaseTarget(targetSpeed);
generationSpeed.tickChaser();
}
@Override
public int feGeneration() {
return (int) Math.abs(getSpeed()*1.5);
}
@Override
public boolean hasElectricitySlot(Direction direction) {
return direction == getBlockState().getValue(FACING).getOpposite();
}
@Override
public int voltageGeneration() {
return (int) Math.abs(getSpeed());
}
@Override
protected void read(CompoundTag compound, boolean clientPacket) {
super.read(compound, clientPacket);
generationSpeed.chase(getGeneratedSpeed(), 1 / 16f, LerpedFloat.Chaser.EXP);
}
@Override
public boolean addToGoggleTooltip(List<Component> tooltip, boolean isPlayerSneaking) {
super.addToGoggleTooltip(tooltip, isPlayerSneaking);
Lang.translate("goggles.generator.production", voltageGeneration())
.style(ChatFormatting.AQUA)
.forGoggles(tooltip, 1);
return true;
}
}

View File

@@ -0,0 +1,49 @@
package com.drmangotea.createindustry.blocks.electricity.generation.large_generator;
import com.drmangotea.createindustry.registry.TFMGBlockEntities;
import com.drmangotea.createindustry.registry.TFMGShapes;
import com.simibubi.create.content.kinetics.base.RotatedPillarKineticBlock;
import com.simibubi.create.foundation.block.IBE;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.RenderShape;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
public class RotorBlock extends RotatedPillarKineticBlock implements IBE<RotorBlockEntity> {
public RotorBlock(Properties properties) {
super(properties);
}
@Override
public Direction.Axis getRotationAxis(BlockState state) {
return state.getValue(AXIS);
}
@Override
public boolean hasShaftTowards(LevelReader world, BlockPos pos, BlockState state, Direction face) {
return face.getAxis() == getRotationAxis(state);
}
@Override
public VoxelShape getShape(BlockState pState, BlockGetter worldIn, BlockPos pos, CollisionContext context) {
return TFMGShapes.ROTOR.get(pState.getValue(AXIS));
}
@Override
public RenderShape getRenderShape(BlockState pState) {
return RenderShape.ENTITYBLOCK_ANIMATED;
}
@Override
public Class<RotorBlockEntity> getBlockEntityClass() {
return RotorBlockEntity.class;
}
@Override
public BlockEntityType<? extends RotorBlockEntity> getBlockEntityType() {
return TFMGBlockEntities.ROTOR.get();
}
}

View File

@@ -0,0 +1,184 @@
package com.drmangotea.createindustry.blocks.electricity.generation.large_generator;
import com.drmangotea.createindustry.registry.TFMGBlocks;
import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.utility.animation.LerpedFloat;
import net.minecraft.ChatFormatting;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import java.util.ArrayList;
import java.util.List;
import static com.simibubi.create.content.kinetics.base.DirectionalKineticBlock.FACING;
import static com.simibubi.create.content.kinetics.base.RotatedPillarKineticBlock.AXIS;
import static net.minecraft.core.Direction.Axis.Z;
public class RotorBlockEntity extends KineticBlockEntity {
LerpedFloat visualSpeed = LerpedFloat.linear();
float angle;
List<BlockPos> statorBlocks = new ArrayList<>();
public boolean valid = false;
public RotorBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
}
@Override
protected AABB createRenderBoundingBox() {
return super.createRenderBoundingBox().inflate(2);
}
@Override
public void write(CompoundTag compound, boolean clientPacket) {
super.write(compound, clientPacket);
}
@Override
protected void read(CompoundTag compound, boolean clientPacket) {
super.read(compound, clientPacket);
visualSpeed.chase(getGeneratedSpeed(), 1 / 128f, LerpedFloat.Chaser.EXP);
}
@Override
public void tick() {
super.tick();
float targetSpeed = getSpeed();
visualSpeed.updateChaseTarget(targetSpeed);
visualSpeed.tickChaser();
angle += visualSpeed.getValue() * 3 / 10f;
angle %= 360;
if(valid)
generateVoltage();
for(BlockPos pos : statorBlocks){
if(!level.getBlockState(pos).is(TFMGBlocks.STATOR.get()))
statorBlocks = new ArrayList<>();
}
if(statorBlocks.toArray().length ==8){
valid = true;
valid = true;
} else {
valid = false;
manageStator();
}
}
public void generateVoltage(){
float power = 2.5f*getSpeed()*(getSpeed()/25f);
for(BlockPos pos : statorBlocks){
if(level.getBlockEntity(pos)instanceof StatorBlockEntity be){
if(be.hasOutput){
be.generation = power;
}
}
}
}
public void manageStator(){
Direction.Axis axis = getBlockState().getValue(AXIS);
statorBlocks = new ArrayList<>();
for(Direction direction : Direction.values()){
if(direction.getAxis() == axis)
continue;
BlockPos pos1 = getBlockPos().relative(direction);
if (canUseStator(pos1)) {
if (axis == Z && direction.getAxis().isVertical()) {
level.setBlock(pos1, TFMGBlocks.STATOR.getDefaultState().setValue(FACING, direction.getOpposite()).setValue(StatorBlock.STATOR_STATE, StatorBlock.StatorState.SIDE).setValue(StatorBlock.VALUE, true), 2);
statorBlocks.add(pos1);
} else {
level.setBlock(pos1, TFMGBlocks.STATOR.getDefaultState().setValue(FACING, direction.getOpposite()).setValue(StatorBlock.STATOR_STATE, StatorBlock.StatorState.SIDE).setValue(StatorBlock.VALUE, false), 2);
statorBlocks.add(pos1);
}
((StatorBlockEntity)level.getBlockEntity(pos1)).setRotor(this);
}
if(direction.getAxis().isVertical())
for(Direction direction2 : Direction.values()) {
if (direction2.getAxis() == axis||direction2.getAxis() == direction.getAxis())
continue;
BlockPos pos = pos1.relative(direction2);
if(canUseStator(pos)) {
BlockState state = TFMGBlocks.STATOR.getDefaultState().setValue(FACING, direction.getOpposite()).setValue(StatorBlock.STATOR_STATE, StatorBlock.StatorState.CORNER).setValue(StatorBlock.VALUE, false);
if (direction == Direction.UP)
state = state.setValue(StatorBlock.VALUE,true);
if(direction2 == Direction.EAST)
state = state.setValue(FACING,Direction.SOUTH);
if(direction2 == Direction.NORTH)
state = state.setValue(FACING,Direction.EAST);
if(direction2 == Direction.SOUTH)
state = state.setValue(FACING,Direction.WEST);
level.setBlock(pos, state, 2);
statorBlocks.add(pos);
((StatorBlockEntity)level.getBlockEntity(pos)).setRotor(this);
}
}
}
}
public boolean canUseStator(BlockPos pos){
return level.getBlockState(pos).is(TFMGBlocks.STATOR.get())&&(
((StatorBlockEntity)level.getBlockEntity(pos)).rotor==null||
((StatorBlockEntity)level.getBlockEntity(pos)).rotor==this.getBlockPos());
}
}

View File

@@ -0,0 +1,99 @@
package com.drmangotea.createindustry.blocks.electricity.generation.large_generator;
import com.drmangotea.createindustry.registry.TFMGPartialModels;
import com.jozufozu.flywheel.api.MaterialManager;
import com.jozufozu.flywheel.api.instance.DynamicInstance;
import com.jozufozu.flywheel.core.materials.model.ModelData;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.content.kinetics.base.KineticBlockEntityInstance;
import com.simibubi.create.content.kinetics.base.flwdata.RotatingData;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import net.minecraft.core.Direction;
import static com.simibubi.create.content.kinetics.base.RotatedPillarKineticBlock.AXIS;
public class RotorInstance extends KineticBlockEntityInstance<RotorBlockEntity> implements DynamicInstance {
protected final RotatingData shaft;
protected final ModelData wheel;
protected final ModelData frame;
protected float lastAngle = Float.NaN;
public RotorInstance(MaterialManager materialManager, RotorBlockEntity blockEntity) {
super(materialManager, blockEntity);
shaft = setup(getRotatingMaterial().getModel(shaft())
.createInstance());
wheel = getTransformMaterial().getModel(blockState)
.createInstance();
Direction direction=null;
Direction.Axis axis = blockState.getValue(AXIS);
if(axis == Direction.Axis.X)
direction = Direction.WEST;
if(axis == Direction.Axis.Y)
direction = Direction.UP;
if(axis == Direction.Axis.Z)
direction = Direction.NORTH;
frame = getTransformMaterial()
.getModel(TFMGPartialModels.AIR_INTAKE_FAN_MEDIUM, blockState, direction)
.createInstance();
animate(blockEntity.angle);
}
@Override
public void beginFrame() {
float partialTicks = AnimationTickHolder.getPartialTicks();
float speed = blockEntity.visualSpeed.getValue(partialTicks) * 3 / 10f;
float angle = blockEntity.angle + speed * partialTicks;
if (Math.abs(angle - lastAngle) < 0.001)
return;
animate(angle);
lastAngle = angle;
if(!blockEntity.valid)
frame.setEmptyTransform();
}
private void animate(float angle) {
PoseStack ms = new PoseStack();
TransformStack msr = TransformStack.cast(ms);
msr.translate(getInstancePosition());
msr.centre()
.rotate(Direction.get(Direction.AxisDirection.POSITIVE, axis), AngleHelper.rad(angle))
.unCentre();
wheel.setTransform(ms);
}
@Override
public void update() {
updateRotation(shaft);
}
@Override
public void updateLight() {
relight(pos, shaft, wheel,frame);
}
@Override
public void remove() {
shaft.delete();
wheel.delete();
frame.delete();
}
}

View File

@@ -0,0 +1,80 @@
package com.drmangotea.createindustry.blocks.electricity.generation.large_generator;
import com.jozufozu.flywheel.backend.Backend;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.simibubi.create.content.kinetics.base.KineticBlockEntityRenderer;
import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.utility.AngleHelper;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.state.BlockState;
import static com.simibubi.create.content.kinetics.base.RotatedPillarKineticBlock.AXIS;
public class RotorRenderer extends KineticBlockEntityRenderer<RotorBlockEntity> {
public RotorRenderer(BlockEntityRendererProvider.Context context) {
super(context);
}
@Override
protected void renderSafe(RotorBlockEntity be, float partialTicks, PoseStack ms, MultiBufferSource buffer,
int light, int overlay) {
super.renderSafe(be, partialTicks, ms, buffer, light, overlay);
if (Backend.canUseInstancing(be.getLevel()))
return;
BlockState blockState = be.getBlockState();
float speed = be.visualSpeed.getValue(partialTicks) * 3 / 10f;
float angle = be.angle + speed * partialTicks;
VertexConsumer vb = buffer.getBuffer(RenderType.solid());
renderFrame(be, ms, light, blockState, angle, vb);
renderFlywheel(be, ms, light, blockState, angle, vb);
}
private void renderFlywheel(RotorBlockEntity be, PoseStack ms, int light, BlockState blockState, float angle,
VertexConsumer vb) {
SuperByteBuffer wheel = CachedBufferer.block(blockState);
kineticRotationTransform(wheel, be, getRotationAxisOf(be), AngleHelper.rad(angle), light);
wheel.renderInto(ms, vb);
}
private void renderFrame(RotorBlockEntity be, PoseStack ms, int light, BlockState blockState, float angle,
VertexConsumer vb) {
ms.pushPose();
Direction direction=null;
Direction.Axis axis = blockState.getValue(AXIS);
if(axis == Direction.Axis.X)
direction = Direction.WEST;
if(axis == Direction.Axis.Y)
direction = Direction.UP;
if(axis == Direction.Axis.Z)
direction = Direction.NORTH;
//SuperByteBuffer frame = CachedBufferer.partialFacing(TFMGPartialModels.ROTOR_FRAME, blockState,direction);
//if(be.valid) {
// frame.renderInto(ms, vb);
//}
ms.popPose();
}
@Override
protected BlockState getRenderedBlockState(RotorBlockEntity be) {
return shaft(getRotationAxisOf(be));
}
}

View File

@@ -0,0 +1,119 @@
package com.drmangotea.createindustry.blocks.electricity.generation.large_generator;
import com.drmangotea.createindustry.blocks.electricity.base.WallMountBlock;
import com.drmangotea.createindustry.registry.TFMGBlockEntities;
import com.simibubi.create.content.equipment.wrench.IWrenchable;
import com.simibubi.create.foundation.block.IBE;
import net.minecraft.core.BlockPos;
import net.minecraft.util.StringRepresentable;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.world.level.block.state.properties.EnumProperty;
public class StatorBlock extends WallMountBlock implements IBE<StatorBlockEntity>, IWrenchable {
public static final BooleanProperty VALUE = BooleanProperty.create("value");
public static final EnumProperty<StatorState> STATOR_STATE = EnumProperty.create("stator_state", StatorState.class);
public StatorBlock(Properties properties) {
super(properties);
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> pBuilder) {
pBuilder.add(STATOR_STATE).add(VALUE);
super.createBlockStateDefinition(pBuilder);
}
@Override
public InteractionResult onWrenched(BlockState state, UseOnContext context) {
Level level = context.getLevel();
BlockPos pos = context.getClickedPos();
BlockEntity be1 = level.getBlockEntity(pos);
if (be1 instanceof StatorBlockEntity be){
if(be.rotor==null){
level.setBlock(pos,state.setValue(STATOR_STATE,StatorState.UNUSED),2);
return InteractionResult.SUCCESS;
}else {
if(state.getValue(STATOR_STATE) == StatorState.SIDE){
RotorBlockEntity rotor = (RotorBlockEntity) level.getBlockEntity(be.rotor);
if(!be.hasOutput) {
if (rotor == null)
return InteractionResult.PASS;
for (BlockPos otherPos : rotor.statorBlocks) {
if (level.getBlockEntity(otherPos) instanceof StatorBlockEntity otherStator) {
if (otherStator.hasOutput)
return InteractionResult.PASS;
}
}
be.hasOutput = true;
return InteractionResult.SUCCESS;
}else {
be.hasOutput = false;
return InteractionResult.SUCCESS;
}
}
}
}
return InteractionResult.PASS;
}
@Override
public Class<StatorBlockEntity> getBlockEntityClass() {
return StatorBlockEntity.class;
}
@Override
public BlockEntityType<? extends StatorBlockEntity> getBlockEntityType() {
return TFMGBlockEntities.STATOR.get();
}
public enum StatorState implements StringRepresentable{
UNUSED("unused"),
SIDE("side"),
CORNER("corner")
;
final String name;
StatorState(String name){
this.name = name;
}
@Override
public String getSerializedName() {
return name;
}
}
}

View File

@@ -0,0 +1,95 @@
package com.drmangotea.createindustry.blocks.electricity.generation.large_generator;
import com.drmangotea.createindustry.blocks.electricity.base.ElectricBlockEntity;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import static com.drmangotea.createindustry.blocks.electricity.generation.large_generator.StatorBlock.STATOR_STATE;
import static net.minecraft.world.level.block.DirectionalBlock.FACING;
public class StatorBlockEntity extends ElectricBlockEntity {
public BlockPos rotor=null;
public boolean hasOutput;
public float generation;
public StatorBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
}
public void tick(){
super.tick();
if(rotor!=null)
if(!(level.getBlockEntity(rotor) instanceof RotorBlockEntity))
rotor = null;
if(rotor == null||getBlockState().getValue(STATOR_STATE) != StatorBlock.StatorState.SIDE)
return;
}
@Override
public float maxVoltage() {
return 10000;
}
public void setRotor(RotorBlockEntity be){
rotor = be.getBlockPos();
}
@Override
public void write(CompoundTag compound, boolean clientPacket) {
super.write(compound, clientPacket);
compound.putBoolean("Output",hasOutput);
}
@Override
protected void read(CompoundTag compound, boolean clientPacket) {
super.read(compound, clientPacket);
hasOutput = compound.getBoolean("Output");
}
@Override
public int feGeneration() {
return (int) generation*30;
}
@Override
public int voltageGeneration() {
return (int) (generation);
}
@Override
public boolean hasElectricitySlot(Direction direction) {
return direction == getBlockState().getValue(FACING).getOpposite()&&hasOutput;
}
@Override
public int FECapacity() {
return 25000;
}
}

View File

@@ -0,0 +1,84 @@
package com.drmangotea.createindustry.blocks.electricity.generation.large_generator;
import com.drmangotea.createindustry.CreateTFMG;
import com.simibubi.create.foundation.data.SpecialBlockStateGen;
import com.tterrag.registrate.providers.DataGenContext;
import com.tterrag.registrate.providers.RegistrateBlockstateProvider;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.client.model.generators.ModelFile;
public class StatorGenerator extends SpecialBlockStateGen {
protected int getXRotation(BlockState state) {
short value;
switch ((Direction)state.getValue(StatorBlock.FACING)) {
case NORTH, SOUTH, WEST, EAST:
value = 0;
break;
case DOWN:
if(state.getValue(StatorBlock.STATOR_STATE)== StatorBlock.StatorState.CORNER) {
value = 0;
}else
value = 90;
break;
case UP:
if(state.getValue(StatorBlock.STATOR_STATE)== StatorBlock.StatorState.CORNER) {
value = 0;
}else
value = 270;
break;
default:
throw new IncompatibleClassChangeError();
}
return value;
}
protected int getYRotation(BlockState state) {
short value;
switch ((Direction)state.getValue(StatorBlock.FACING)) {
case NORTH, DOWN, UP:
value = 0;
break;
case SOUTH:
value = 180;
break;
case WEST:
value = 270;
break;
case EAST:
value = 90;
break;
default:
throw new IncompatibleClassChangeError();
}
return value;
}
@Override
public <T extends Block> ModelFile getModel(DataGenContext<Block, T> ctx, RegistrateBlockstateProvider prov,
BlockState state) {
String path = "block/stator/block_"
+ state.getValue(StatorBlock.STATOR_STATE).getSerializedName()
;
if(state.getValue(StatorBlock.VALUE)&&state.getValue(StatorBlock.STATOR_STATE)== StatorBlock.StatorState.CORNER)
path = path + "_up";
if(state.getValue(StatorBlock.VALUE)&&state.getValue(StatorBlock.STATOR_STATE)== StatorBlock.StatorState.SIDE)
path = path + "_rotated";
return prov.models()
.getExistingFile(CreateTFMG.asResource(path));
}
}

View File

@@ -0,0 +1,32 @@
package com.drmangotea.createindustry.blocks.electricity.generation.large_generator;
import com.drmangotea.createindustry.registry.TFMGPartialModels;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.simibubi.create.foundation.blockEntity.renderer.SafeBlockEntityRenderer;
import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import static com.simibubi.create.content.kinetics.base.DirectionalKineticBlock.FACING;
public class StatorRenderer extends SafeBlockEntityRenderer<StatorBlockEntity> {
public StatorRenderer(BlockEntityRendererProvider.Context context) {
}
@Override
protected void renderSafe(StatorBlockEntity be, float partialTicks, PoseStack ms, MultiBufferSource buffer, int light, int overlay) {
ms.pushPose();
VertexConsumer vb = buffer.getBuffer(RenderType.solid());
SuperByteBuffer output = CachedBufferer.partialFacing(TFMGPartialModels.STATOR_OUTPUT, be.getBlockState(),be.getBlockState().getValue(FACING).getOpposite());
if(be.hasOutput)
output.renderInto(ms, vb);
ms.popPose();
}
}

View File

@@ -0,0 +1,76 @@
package com.drmangotea.createindustry.blocks.electricity.lights;
import com.drmangotea.createindustry.blocks.electricity.base.WallMountBlock;
import com.drmangotea.createindustry.registry.TFMGBlockEntities;
import com.drmangotea.createindustry.registry.TFMGShapes;
import com.simibubi.create.content.equipment.wrench.IWrenchable;
import com.simibubi.create.foundation.block.IBE;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.SimpleWaterloggedBlock;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.world.level.block.state.properties.IntegerProperty;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.material.Fluids;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
public class LightBulbBlock extends WallMountBlock implements IBE<LightBulbBlockEntity>, SimpleWaterloggedBlock, IWrenchable {
public static final IntegerProperty LIGHT = BlockStateProperties.LEVEL;
public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED;
public LightBulbBlock(Properties properties) {
super(properties);
this.registerDefaultState(this.stateDefinition.any().setValue(LIGHT, 0).setValue(WATERLOGGED, false));
}
@Override
public VoxelShape getShape(BlockState pState, BlockGetter worldIn, BlockPos pos, CollisionContext context) {
return TFMGShapes.LIGHT_BULB.get(pState.getValue(FACING));
}
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> p_153687_) {
p_153687_.add(LIGHT, WATERLOGGED,FACING);
}
public BlockState updateShape(BlockState p_153680_, Direction p_153681_, BlockState p_153682_, LevelAccessor p_153683_, BlockPos p_153684_, BlockPos p_153685_) {
if (p_153680_.getValue(WATERLOGGED)) {
p_153683_.scheduleTick(p_153684_, Fluids.WATER, Fluids.WATER.getTickDelay(p_153683_));
}
return super.updateShape(p_153680_, p_153681_, p_153682_, p_153683_, p_153684_, p_153685_);
}
public FluidState getFluidState(BlockState p_153699_) {
return p_153699_.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(p_153699_);
}
@Override
public Class<LightBulbBlockEntity> getBlockEntityClass() {
return LightBulbBlockEntity.class;
}
@Override
public BlockEntityType<? extends LightBulbBlockEntity> getBlockEntityType() {
return TFMGBlockEntities.LIGHT_BULB.get();
}
}

View File

@@ -0,0 +1,107 @@
package com.drmangotea.createindustry.blocks.electricity.lights;
import com.drmangotea.createindustry.blocks.electricity.base.ElectricBlockEntity;
import com.simibubi.create.foundation.utility.animation.LerpedFloat;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import static com.drmangotea.createindustry.blocks.electricity.base.WallMountBlock.FACING;
import static com.drmangotea.createindustry.blocks.electricity.lights.LightBulbBlock.LIGHT;
public class LightBulbBlockEntity extends ElectricBlockEntity {
public LerpedFloat glow = LerpedFloat.linear();
boolean signalChanged;
boolean hasSignal;
public LightBulbBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
}
@Override
public void tick() {
super.tick();
if(!hasSignal&&energy.getEnergyStored()!=0) {
glow.chase(voltage, 0.4, LerpedFloat.Chaser.EXP);
glow.tickChaser();
if(voltage!=0)
useEnergy(1);
if ((int) Math.min(voltage / 10, 15) != getBlockState().getValue(LIGHT))
level.setBlock(getBlockPos(), getBlockState().setValue(LIGHT, (int) Math.min(voltage / 10, 15)), 2);
}else {
if (getBlockState().getValue(LIGHT)!=0)
level.setBlock(getBlockPos(), getBlockState().setValue(LIGHT, 0), 2);
glow.chase(0, 0.4, LerpedFloat.Chaser.EXP);
glow.tickChaser();
}
if (signalChanged) {
signalChanged = false;
analogSignalChanged(level.getBestNeighborSignal(worldPosition));
}
}
public void neighbourChanged() {
if (!hasLevel())
return;
boolean powered = level.getBestNeighborSignal(worldPosition)>0;
if (powered != hasSignal)
signalChanged = true;
}
@Override
public void lazyTick() {
super.lazyTick();
neighbourChanged();
}
protected void analogSignalChanged(int newSignal) {
hasSignal = newSignal > 0;
}
@Override
public void explode() {
level.playSound(null, getBlockPos(), SoundEvents.GLASS_BREAK, SoundSource.BLOCKS, 2.0F,
level.random.nextFloat() * 0.4F + 0.8F);
level.destroyBlock(getBlockPos(),false);
sendStuff();
// level.explode(null, getBlockPos().getX()+0.5, getBlockPos().getY()+0.5, getBlockPos().getZ()+0.5, 0.1f, Explosion.BlockInteraction.BREAK);
// TFMGUtils.createFireExplosion(level, getBlockPos(),5,.1f);
}
@Override
public boolean hasElectricitySlot(Direction direction) {
return direction == getBlockState().getValue(FACING).getOpposite();
}
}

View File

@@ -0,0 +1,53 @@
package com.drmangotea.createindustry.blocks.electricity.lights;
import com.drmangotea.createindustry.blocks.electricity.base.WallMountBlock;
import com.drmangotea.createindustry.registry.TFMGBlocks;
import com.drmangotea.createindustry.registry.TFMGPartialModels;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.foundation.blockEntity.renderer.SafeBlockEntityRenderer;
import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.render.RenderTypes;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import net.minecraft.world.level.block.state.BlockState;
public class LightBulbRenderer extends SafeBlockEntityRenderer<LightBulbBlockEntity> {
public LightBulbRenderer(BlockEntityRendererProvider.Context context) {
}
@Override
protected void renderSafe(LightBulbBlockEntity be, float partialTicks, PoseStack ms, MultiBufferSource buffer, int light, int overlay) {
BlockState blockState = be.getBlockState();
TransformStack msr = TransformStack.cast(ms);
ms.pushPose();
float glow = be.glow.getValue(partialTicks);
int color = Math.min(100,(int) (glow/0.2f));
if(be.glow.getValue()!=0) {
// if(blockState.is(TFMGBlocks.INDUSTRIAL_LIGHT.get())){
// CachedBufferer.partialFacing(TFMGPartialModels.INDUSTRIAL_LIGHT, blockState, blockState.getValue(WallMountBlock.FACING))
// .light((int) glow * 3 + 40)
// .color(color, color, (int) (color * 0.8), 255)
// .disableDiffuse()
// .renderInto(ms, buffer.getBuffer(RenderTypes.getAdditive()));
//
// }else
CachedBufferer.partialFacing(TFMGPartialModels.LIGHT_BULB, blockState, blockState.getValue(WallMountBlock.FACING))
.light((int) glow * 3 + 40)
.color(color, color, (int) (color * 0.8), 255)
.disableDiffuse()
.renderInto(ms, buffer.getBuffer(RenderTypes.getAdditive()));
}
ms.popPose();
}
}

View File

@@ -0,0 +1,146 @@
package com.drmangotea.createindustry.blocks.electricity.lights.neon;
import com.drmangotea.createindustry.registry.TFMGBlockEntities;
import com.drmangotea.createindustry.registry.TFMGBlocks;
import com.drmangotea.createindustry.registry.TFMGShapes;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.content.equipment.clipboard.ClipboardEntry;
import com.simibubi.create.content.trains.display.FlapDisplayBlockEntity;
import com.simibubi.create.foundation.block.IBE;
import com.simibubi.create.foundation.placement.IPlacementHelper;
import com.simibubi.create.foundation.placement.PlacementHelpers;
import com.simibubi.create.foundation.placement.PlacementOffset;
import com.simibubi.create.foundation.placement.PoleHelper;
import com.simibubi.create.foundation.utility.Components;
import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.Tag;
import net.minecraft.network.chat.Component;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.DyeColor;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.RotatedPillarBlock;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
import java.util.List;
import java.util.function.Predicate;
public class NeonTubeBlock extends RotatedPillarBlock implements IBE<NeonTubeBlockEntity> {
public static final int placementHelperId = PlacementHelpers.register(new PlacementHelper());
public static final BooleanProperty ACTIVE = BooleanProperty.create("active");
public NeonTubeBlock(Properties pProperties) {
super(pProperties);
this.registerDefaultState(this.defaultBlockState().setValue(ACTIVE, false));
}
@Override
public VoxelShape getShape(BlockState pState, BlockGetter pLevel, BlockPos pPos, CollisionContext pContext) {
return TFMGShapes.CABLE_TUBE.get(pState.getValue(AXIS));
}
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> pBuilder) {
pBuilder.add(ACTIVE,AXIS);
}
@Override
public InteractionResult use(BlockState pState, Level pLevel, BlockPos pPos, Player player, InteractionHand pHand,
BlockHitResult pHit) {
if (player.isShiftKeyDown())
return InteractionResult.PASS;
ItemStack heldItem = player.getItemInHand(pHand);
NeonTubeBlockEntity be = getBlockEntity(pLevel, pPos);
DyeColor dye = DyeColor.getColor(heldItem);
if (be != null){
if (dye != null) {
pLevel.playSound(null, pPos, SoundEvents.DYE_USE, SoundSource.BLOCKS, 1.0F, 1.0F);
be.setColor(dye);
}
}
ItemStack itemInHand = player.getItemInHand(pHand);
IPlacementHelper helper = PlacementHelpers.get(placementHelperId);
if (helper.matchesItem(itemInHand))
return helper.getOffset(player, pLevel, pState, pPos, pHit)
.placeInWorld(pLevel, (BlockItem) itemInHand.getItem(), player, pHand, pHit);
return InteractionResult.SUCCESS;
}
@Override
public Class<NeonTubeBlockEntity> getBlockEntityClass() {
return NeonTubeBlockEntity.class;
}
@Override
public BlockEntityType<? extends NeonTubeBlockEntity> getBlockEntityType() {
return TFMGBlockEntities.NEON_TUBE.get();
}
////
@MethodsReturnNonnullByDefault
private static class PlacementHelper extends PoleHelper<Direction.Axis> {
private PlacementHelper() {
super(state -> state.getBlock() instanceof NeonTubeBlock, state -> state.getValue(AXIS), AXIS);
}
@Override
public Predicate<ItemStack> getItemPredicate() {
return i -> i.getItem() instanceof BlockItem
&& ((BlockItem) i.getItem()).getBlock() instanceof NeonTubeBlock;
}
@Override
public Predicate<BlockState> getStatePredicate() {
return s -> s.getBlock() instanceof NeonTubeBlock;
}
@Override
public PlacementOffset getOffset(Player player, Level world, BlockState state, BlockPos pos,
BlockHitResult ray) {
PlacementOffset offset = super.getOffset(player, world, state, pos, ray);
if (offset.isSuccessful())
offset.withTransform(offset.getTransform()
.andThen(s -> TFMGBlocks.NEON_TUBE.getDefaultState().setValue(AXIS,state.getValue(AXIS))));
return offset;
}
}
}

View File

@@ -0,0 +1,130 @@
package com.drmangotea.createindustry.blocks.electricity.lights.neon;
import com.drmangotea.createindustry.blocks.electricity.cable_blocks.CableTubeBlockEntity;
import com.simibubi.create.Create;
import com.simibubi.create.foundation.utility.NBTHelper;
import com.simibubi.create.foundation.utility.animation.LerpedFloat;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.item.DyeColor;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import static com.drmangotea.createindustry.blocks.electricity.lights.LightBulbBlock.LIGHT;
import static com.drmangotea.createindustry.blocks.electricity.lights.neon.NeonTubeBlock.ACTIVE;
public class NeonTubeBlockEntity extends CableTubeBlockEntity {
public DyeColor color;
boolean shouldDestroy = false;
int red = 250;
int green = 0;
int blue = 0;
public LerpedFloat glow = LerpedFloat.linear();
public NeonTubeBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
color = DyeColor.WHITE;
}
@Override
public void tick() {
super.tick();
if(shouldDestroy){
level.destroyBlock(getBlockPos(),false);
return;
}
if(energy.getEnergyStored()!=0&&voltage!=0) {
glow.chase(voltage, 0.4, LerpedFloat.Chaser.EXP);
glow.tickChaser();
if(voltage!=0) {
useEnergy(1);
if (!getBlockState().getValue(ACTIVE))
level.setBlock(getBlockPos(), getBlockState().setValue(ACTIVE,true), 2);
}
}else {
//if (getBlockState().getValue(ACTIVE))
level.setBlock(getBlockPos(), getBlockState().setValue(ACTIVE,false), 2);
glow.chase(0, 0.4, LerpedFloat.Chaser.EXP);
glow.tickChaser();
}
}
@Override
public void explode() {
voltage = 0;
level.playSound(null, getBlockPos(), SoundEvents.GLASS_BREAK, SoundSource.BLOCKS, 2.0F,
level.random.nextFloat() * 0.4F + 0.8F);
level.destroyBlock(getBlockPos(),false);
shouldDestroy = true;
sendStuff();
}
public void setColor(DyeColor color) {
if(color==DyeColor.BLACK||color == DyeColor.LIGHT_GRAY|| color == DyeColor.GRAY)
changeColor();
this.color = color;
notifyUpdate();
}
@Override
public float maxVoltage() {
return 300;
}
public void changeColor(){
red = Create.RANDOM.nextInt(255);
green = Create.RANDOM.nextInt(255);
blue = Create.RANDOM.nextInt(255);
}
@Override
public void write(CompoundTag compound, boolean clientPacket) {
super.write(compound, clientPacket);
NBTHelper.writeEnum(compound,"color",color);
compound.putInt("red",red);
compound.putInt("green",green);
compound.putInt("blue",blue);
}
@Override
protected void read(CompoundTag compound, boolean clientPacket) {
super.read(compound, clientPacket);
color = NBTHelper.readEnum(compound,"color",DyeColor.class);
red = compound.getInt("red");
green = compound.getInt("green");
blue = compound.getInt("blue");
}
}

View File

@@ -0,0 +1,60 @@
package com.drmangotea.createindustry.blocks.electricity.lights.neon;
import com.drmangotea.createindustry.blocks.electricity.base.WallMountBlock;
import com.drmangotea.createindustry.registry.TFMGPartialModels;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.Create;
import com.simibubi.create.foundation.blockEntity.renderer.SafeBlockEntityRenderer;
import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.render.RenderTypes;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import net.minecraft.core.Direction;
import net.minecraft.world.item.DyeColor;
import net.minecraft.world.level.block.state.BlockState;
import static net.minecraft.world.level.block.RotatedPillarBlock.AXIS;
public class NeonTubeRenderer extends SafeBlockEntityRenderer<NeonTubeBlockEntity> {
public NeonTubeRenderer(BlockEntityRendererProvider.Context context) {}
@Override
protected void renderSafe(NeonTubeBlockEntity be, float partialTicks, PoseStack ms, MultiBufferSource bufferSource, int light, int overlay) {
BlockState blockState = be.getBlockState();
TransformStack msr = TransformStack.cast(ms);
ms.pushPose();
float glow = be.glow.getValue(partialTicks);
int color = be.color.getTextColor();
if(be.glow.getValue()!=0)
if(be.color != DyeColor.BLACK) {
CachedBufferer.partialFacing(TFMGPartialModels.NEON_TUBE_LIGHT, blockState, Direction.fromAxisAndDirection(blockState.getValue(AXIS), Direction.AxisDirection.POSITIVE))
.light((int) glow * 3 + 40)
.color(color)
.disableDiffuse()
.renderInto(ms, bufferSource.getBuffer(RenderTypes.getAdditive()));
} else
CachedBufferer.partialFacing(TFMGPartialModels.NEON_TUBE_LIGHT, blockState, Direction.fromAxisAndDirection(blockState.getValue(AXIS), Direction.AxisDirection.POSITIVE))
.light((int) glow * 3 + 40)
.color(be.red,be.green,be.blue,255)
.disableDiffuse()
.renderInto(ms, bufferSource.getBuffer(RenderTypes.getAdditive()));
ms.popPose();
}
}

View File

@@ -0,0 +1,94 @@
package com.drmangotea.createindustry.blocks.electricity.lights.rgb;
import com.drmangotea.createindustry.blocks.electricity.base.WallMountBlock;
import com.drmangotea.createindustry.registry.TFMGBlockEntities;
import com.drmangotea.createindustry.registry.TFMGShapes;
import com.simibubi.create.content.equipment.wrench.IWrenchable;
import com.simibubi.create.foundation.block.IBE;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.SimpleWaterloggedBlock;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.world.level.block.state.properties.IntegerProperty;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.material.Fluids;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
public class RGBLightBulbBlock extends WallMountBlock implements IBE<RGBLightBulbBlockEntity>, SimpleWaterloggedBlock, IWrenchable {
public static final IntegerProperty LIGHT = BlockStateProperties.LEVEL;
public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED;
public RGBLightBulbBlock(Properties properties) {
super(properties);
this.registerDefaultState(this.stateDefinition.any().setValue(LIGHT, 0).setValue(WATERLOGGED, false));
}
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> p_153687_) {
p_153687_.add(LIGHT, WATERLOGGED,FACING);
}
public BlockState updateShape(BlockState p_153680_, Direction p_153681_, BlockState p_153682_, LevelAccessor p_153683_, BlockPos p_153684_, BlockPos p_153685_) {
if (p_153680_.getValue(WATERLOGGED)) {
p_153683_.scheduleTick(p_153684_, Fluids.WATER, Fluids.WATER.getTickDelay(p_153683_));
}
return super.updateShape(p_153680_, p_153681_, p_153682_, p_153683_, p_153684_, p_153685_);
}
@Override
public VoxelShape getShape(BlockState pState, BlockGetter worldIn, BlockPos pos, CollisionContext context) {
return TFMGShapes.LIGHT_BULB.get(pState.getValue(FACING));
}
public FluidState getFluidState(BlockState p_153699_) {
return p_153699_.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(p_153699_);
}
@Override
public InteractionResult onWrenched(BlockState state, UseOnContext context) {
Level level = context.getLevel();
BlockPos pos = context.getClickedPos();
Direction direction = context.getClickedFace();
return onBlockEntityUse(level, pos, be -> {
be.changeColor();
return InteractionResult.SUCCESS;
});
}
@Override
public Class<RGBLightBulbBlockEntity> getBlockEntityClass() {
return RGBLightBulbBlockEntity.class;
}
@Override
public BlockEntityType<? extends RGBLightBulbBlockEntity> getBlockEntityType() {
return TFMGBlockEntities.RGB_LIGHT_BULB.get();
}
}

View File

@@ -0,0 +1,47 @@
package com.drmangotea.createindustry.blocks.electricity.lights.rgb;
import com.drmangotea.createindustry.blocks.electricity.lights.LightBulbBlockEntity;
import com.simibubi.create.Create;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
public class RGBLightBulbBlockEntity extends LightBulbBlockEntity {
int red = 250;
int green = 0;
int blue = 0;
public RGBLightBulbBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
}
public void changeColor(){
red = Create.RANDOM.nextInt(255);
green = Create.RANDOM.nextInt(255);
blue = Create.RANDOM.nextInt(255);
}
@Override
public void write(CompoundTag compound, boolean clientPacket) {
super.write(compound, clientPacket);
compound.putInt("red",red);
compound.putInt("green",green);
compound.putInt("blue",blue);
}
@Override
protected void read(CompoundTag compound, boolean clientPacket) {
super.read(compound, clientPacket);
red = compound.getInt("red");
green = compound.getInt("green");
blue = compound.getInt("blue");
}
}

View File

@@ -0,0 +1,54 @@
package com.drmangotea.createindustry.blocks.electricity.lights.rgb;
import com.drmangotea.createindustry.blocks.electricity.base.WallMountBlock;
import com.drmangotea.createindustry.registry.TFMGPartialModels;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.foundation.blockEntity.renderer.SafeBlockEntityRenderer;
import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.render.RenderTypes;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import net.minecraft.world.level.block.state.BlockState;
import java.util.Random;
public class RGBLightBulbRenderer extends SafeBlockEntityRenderer<RGBLightBulbBlockEntity> {
public RGBLightBulbRenderer(BlockEntityRendererProvider.Context context) {
}
@Override
protected void renderSafe(RGBLightBulbBlockEntity be, float partialTicks, PoseStack ms, MultiBufferSource buffer, int light, int overlay) {
BlockState blockState = be.getBlockState();
TransformStack msr = TransformStack.cast(ms);
ms.pushPose();
float glow = be.glow.getValue(partialTicks);
int color = Math.min(200,(int) (glow/0.8f));
int seed = (int) glow;
Random random = new Random(seed);
// CachedBufferer.partial(AllPartialModels.DISPLAY_LINK_TUBE, blockState)
// .light(LightTexture.FULL_BRIGHT)
// .renderInto(ms, buffer.getBuffer(RenderType.translucent()));
if(be.glow.getValue()!=0)
CachedBufferer.partialFacing(TFMGPartialModels.LIGHT_BULB, blockState,blockState.getValue(WallMountBlock.FACING))
.light((int) glow*3+40)
.color(be.red,be.green,be.blue,255)
.disableDiffuse()
.renderInto(ms, buffer.getBuffer(RenderTypes.getAdditive()));
ms.popPose();
}
}

View File

@@ -0,0 +1,52 @@
package com.drmangotea.createindustry.blocks.electricity.polarizer;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.foundation.blockEntity.renderer.SafeBlockEntityRenderer;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.block.model.ItemTransforms.TransformType;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import net.minecraft.client.renderer.entity.ItemRenderer;
import net.minecraft.core.Direction;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.HorizontalDirectionalBlock;
import net.minecraft.world.level.block.state.BlockState;
public class PolarizeRenderer extends SafeBlockEntityRenderer<PolarizerBlockEntity> {
public PolarizeRenderer(BlockEntityRendererProvider.Context context) {}
@Override
protected void renderSafe(PolarizerBlockEntity be, float partialTicks, PoseStack ms, MultiBufferSource buffer,
int light, int overlay) {
ItemStack heldItem = be.inventory.getItem(0);
if (heldItem.isEmpty())
return;
BlockState blockState = be.getBlockState();
ItemRenderer itemRenderer = Minecraft.getInstance()
.getItemRenderer();
boolean blockItem = itemRenderer.getModel(heldItem, null, null, 0)
.isGui3d();
ms.pushPose();
TransformStack msr = TransformStack.cast(ms)
.centre()
.rotateY(blockState.getValue(HorizontalDirectionalBlock.FACING).getAxis()== Direction.Axis.X ? 90 : 0)
.translate(0, 0.4, 0)
.scale(blockItem ? .5f : .375f);
itemRenderer.renderStatic(heldItem, TransformType.FIXED, light, overlay, ms, buffer, 0);
ms.popPose();
}
}

View File

@@ -0,0 +1,59 @@
package com.drmangotea.createindustry.blocks.electricity.polarizer;
import com.drmangotea.createindustry.blocks.TFMGHorizontalDirectionalBlock;
import com.drmangotea.createindustry.registry.TFMGBlockEntities;
import com.drmangotea.createindustry.registry.TFMGShapes;
import com.simibubi.create.content.equipment.wrench.IWrenchable;
import com.simibubi.create.foundation.block.IBE;
import net.minecraft.core.BlockPos;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
public class PolarizerBlock extends TFMGHorizontalDirectionalBlock implements IBE<PolarizerBlockEntity>, IWrenchable {
public PolarizerBlock(Properties p_54120_) {
super(p_54120_);
}
@Override
public InteractionResult use(BlockState pState, Level level, BlockPos pos, Player player, InteractionHand pHand, BlockHitResult pHit) {
ItemStack inHand = player.getItemInHand(pHand);
if (level.getBlockEntity(pos) instanceof PolarizerBlockEntity be)
if (be.playerInteract(player, pHand))
return InteractionResult.SUCCESS;
return InteractionResult.PASS;
}
@Override
public void onRemove(BlockState state, Level worldIn, BlockPos pos, BlockState newState, boolean isMoving) {
IBE.onRemove(state, worldIn, pos, newState);
}
@Override
public VoxelShape getShape(BlockState pState, BlockGetter pLevel, BlockPos pPos, CollisionContext pContext) {
return TFMGShapes.SLAB;
}
@Override
public Class<PolarizerBlockEntity> getBlockEntityClass() {
return PolarizerBlockEntity.class;
}
@Override
public BlockEntityType<? extends PolarizerBlockEntity> getBlockEntityType() {
return TFMGBlockEntities.POLARIZER.get();
}
}

View File

@@ -0,0 +1,194 @@
package com.drmangotea.createindustry.blocks.electricity.polarizer;
import com.drmangotea.createindustry.base.util.TFMGUtils;
import com.drmangotea.createindustry.blocks.electricity.base.ElectricBlockEntity;
import com.drmangotea.createindustry.registry.TFMGItems;
import com.simibubi.create.content.equipment.goggles.IHaveGoggleInformation;
import com.simibubi.create.foundation.item.ItemHelper;
import com.simibubi.create.foundation.item.SmartInventory;
import com.simibubi.create.foundation.utility.Lang;
import net.minecraft.ChatFormatting;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.world.Containers;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ForgeCapabilities;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.items.IItemHandlerModifiable;
import net.minecraftforge.items.wrapper.CombinedInvWrapper;
import javax.annotation.Nonnull;
import java.util.List;
import static net.minecraft.world.level.block.HorizontalDirectionalBlock.FACING;
public class PolarizerBlockEntity extends ElectricBlockEntity implements IHaveGoggleInformation {
public LazyOptional<IItemHandlerModifiable> itemCapability;
public SmartInventory inventory;
public int timer = 0;
public PolarizerBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
this.inventory = new SmartInventory(1, this).forbidInsertion().withMaxStackSize(1);
this.itemCapability = LazyOptional.of(() -> new CombinedInvWrapper(this.inventory));
}
@Override
public void tick() {
super.tick();
if(voltage<200) {
timer = 0;
return;
}
if(!inventory.getItem(0).is(TFMGItems.STEEL_INGOT.get())) {
timer = 0;
return;
}
if(energy.getEnergyStored()!=0) {
useEnergy(250);
if (!inventory.isEmpty()) {
if (timer < 100) {
timer++;
} else {
timer = 0;
inventory.setStackInSlot(0, TFMGItems.MAGNETIC_INGOT.asStack());
TFMGUtils.spawnElectricParticles(level,getBlockPos());
sendStuff();
}
}
}else timer =0;
}
@Override
public void destroy() {
super.destroy();
Containers.dropItemStack(level, getBlockPos().getX(), getBlockPos().getY(), getBlockPos().getZ(), inventory.getStackInSlot(0));
}
@Nonnull
public <T> LazyOptional<T> getCapability(@Nonnull Capability<T> cap, Direction side) {
return cap == ForgeCapabilities.ITEM_HANDLER ? this.itemCapability.cast() : super.getCapability(cap, side);
}
public boolean playerInteract(Player player, InteractionHand hand){
;
if(inventory.isEmpty()) {
if (player.getItemInHand(hand).is(TFMGItems.STEEL_INGOT.get())) {
inventory.setStackInSlot(0, TFMGItems.STEEL_INGOT.asStack());
sendStuff();
player.getItemInHand(hand).shrink(1);
return true;
}
} else {
if (player.getItemInHand(hand).isEmpty()) {
player.setItemInHand(hand,inventory.getItem(0));
inventory.setStackInSlot(0, Blocks.AIR.asItem().getDefaultInstance());
sendStuff();
return true;
}
}
return false;
}
@Override
@SuppressWarnings("removal")
public boolean addToGoggleTooltip(List<Component> tooltip, boolean isPlayerSneaking) {
if(energy.getEnergyStored()==0){
Lang.translate("goggles.electric_machine.no_power")
.style(ChatFormatting.DARK_RED)
.forGoggles(tooltip, 1);
return true;
}
if(energy.getEnergyStored()==0) {
Lang.translate("goggles.electric_machine.insufficient_voltage")
.style(ChatFormatting.RED)
.forGoggles(tooltip, 1);
return true;
}
if(timer>0) {
Lang.translate("goggles.blast_furnace.status.running")
.style(ChatFormatting.GOLD)
.forGoggles(tooltip, 1);
Lang.translate("goggles.coke_oven.progress", timer)
.style(ChatFormatting.GREEN)
.add(Lang.translate("goggles.misc.percent_symbol")
.style(ChatFormatting.GREEN))
.forGoggles(tooltip, 1);
}
else
Lang.translate("goggles.blast_furnace.status.off")
.style(ChatFormatting.GOLD)
.forGoggles(tooltip, 1);
return true;
}
@Override
public void write(CompoundTag tag, boolean clientPacket) {
tag.put("Inventory", this.inventory.serializeNBT());
//tag.put("Item", heldItem.serializeNBT());
super.write(tag, clientPacket);
}
@Override
protected void read(CompoundTag tag, boolean clientPacket) {
this.inventory.deserializeNBT(tag.getCompound("Inventory"));
//heldItem = ItemStack.of(tag.getCompound("Item"));
super.read(tag, clientPacket);
}
@Override
public boolean hasElectricitySlot(Direction direction) {
return direction == getBlockState().getValue(FACING).getCounterClockWise();
}
}

View File

@@ -0,0 +1,33 @@
package com.drmangotea.createindustry.blocks.electricity.resistors;
import com.drmangotea.createindustry.blocks.TFMGHorizontalDirectionalBlock;
import com.drmangotea.createindustry.registry.TFMGBlockEntities;
import com.drmangotea.createindustry.registry.TFMGShapes;
import com.simibubi.create.foundation.block.IBE;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
public class ResistorBlock extends TFMGHorizontalDirectionalBlock implements IBE<ResistorBlockEntity> {
public ResistorBlock(Properties p_54120_) {
super(p_54120_);
}
@Override
public Class<ResistorBlockEntity> getBlockEntityClass() {
return ResistorBlockEntity.class;
}
@Override
public VoxelShape getShape(BlockState pState, BlockGetter worldIn, BlockPos pos, CollisionContext context) {
return TFMGShapes.RESISTOR.get(pState.getValue(FACING));
}
@Override
public BlockEntityType<? extends ResistorBlockEntity> getBlockEntityType() {
return TFMGBlockEntities.RESISTOR.get();
}
}

View File

@@ -0,0 +1,135 @@
package com.drmangotea.createindustry.blocks.electricity.resistors;
import com.drmangotea.createindustry.blocks.electricity.base.ElectricBlockEntity;
import com.drmangotea.createindustry.blocks.electricity.base.IElectricBlock;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
import com.simibubi.create.foundation.blockEntity.behaviour.ValueBoxTransform;
import com.simibubi.create.foundation.blockEntity.behaviour.scrollValue.ScrollValueBehaviour;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.network.chat.Component;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec3;
import java.util.List;
import static net.minecraft.world.level.block.HorizontalDirectionalBlock.FACING;
public class ResistorBlockEntity extends ElectricBlockEntity {
protected ScrollValueBehaviour outputVoltage;
public ResistorBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
}
@Override
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
super.addBehaviours(behaviours);
int max = 250;
outputVoltage = new ScrollValueBehaviour(Lang.translateDirect("resistor.allowed_voltage"),
this, new ResistorValueBox());
outputVoltage.between(0, max);
outputVoltage.value = 50;
//outputVoltage.withCallback(i -> this.updateVoltageOutput());
behaviours.add(outputVoltage);
}
public void updateVoltageOutput(){
}
public int getVoltageOutput(){
return Math.min(outputVoltage.getValue(),voltage);
}
@Override
public void tick() {
super.tick();
BlockEntity be1 = level.getBlockEntity(getBlockPos().relative(getBlockState().getValue(FACING)));
if (be1 instanceof IElectricBlock be2)
if (be2.hasElectricitySlot(getBlockState().getValue(FACING).getOpposite())) {
sendCharge(be2);
}
}
public void sendCharge(IElectricBlock be){
int maxPossibleTransfer = Math.min(transferSpeed(),Math.min(energy.getEnergyStored(),be.getForgeEnergy().getMaxEnergyStored()-be.getForgeEnergy().getEnergyStored()));
if(be.getForgeEnergy().getEnergyStored() < getForgeEnergy().getEnergyStored()) {
be.getForgeEnergy().receiveEnergy(maxPossibleTransfer, false);
getForgeEnergy().extractEnergy(maxPossibleTransfer, false);
}
}
@Override
public boolean addToGoggleTooltip(List<Component> tooltip, boolean isPlayerSneaking) {
return false;
}
class ResistorValueBox extends ValueBoxTransform.Sided {
@Override
protected Vec3 getSouthLocation() {
return VecHelper.voxelSpace(8, 8, 12.5);
}
@Override
public Vec3 getLocalOffset(BlockState state) {
Direction facing = state.getValue(FACING);
return super.getLocalOffset(state).add(Vec3.atLowerCornerOf(facing.getNormal())
.scale(-1 / 16f));
}
@Override
public void rotate(BlockState state, PoseStack ms) {
super.rotate(state, ms);
Direction facing = state.getValue(FACING);
if (facing.getAxis() == Direction.Axis.Y)
return;
if (getSide() != Direction.UP)
return;
TransformStack.cast(ms)
.rotateZ(-AngleHelper.horizontalAngle(facing) + 180);
}
@Override
protected boolean isSideActive(BlockState state, Direction direction) {
Direction facing = state.getValue(FACING);
if (direction!=Direction.UP)
return false;
return direction.getAxis() != facing.getAxis();
}
}
@Override
public float maxVoltage() {
return 1500;
}
@Override
public boolean hasElectricitySlot(Direction direction) {
return direction == getBlockState().getValue(FACING).getOpposite();
}
}

View File

@@ -0,0 +1,45 @@
package com.drmangotea.createindustry.blocks.electricity.transformer;
import com.drmangotea.createindustry.registry.TFMGBlockEntities;
import com.simibubi.create.content.equipment.wrench.IWrenchable;
import com.simibubi.create.foundation.block.IBE;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
public class CoilBlock extends Block implements IBE<CoilBlockEntity>, IWrenchable {
public static final BooleanProperty CAN_EXTRACT = BooleanProperty.create("can_extract");
public CoilBlock(Properties p_49795_) {
super(p_49795_);
registerDefaultState(defaultBlockState().setValue(CAN_EXTRACT, false));
}
public InteractionResult onWrenched(BlockState state, UseOnContext context) {
context.getLevel().setBlock(context.getClickedPos(),state.setValue(CAN_EXTRACT,!state.getValue(CAN_EXTRACT)),2);
return InteractionResult.SUCCESS;
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
super.createBlockStateDefinition(builder);
builder.add(CAN_EXTRACT);
}
@Override
public Class<CoilBlockEntity> getBlockEntityClass() {
return CoilBlockEntity.class;
}
@Override
public BlockEntityType<? extends CoilBlockEntity> getBlockEntityType() {
return TFMGBlockEntities.COIL.get();
}
}

View File

@@ -0,0 +1,155 @@
package com.drmangotea.createindustry.blocks.electricity.transformer;
import com.drmangotea.createindustry.blocks.electricity.base.ElectricBlockEntity;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import java.util.ArrayList;
public class CoilBlockEntity extends ElectricBlockEntity {
public boolean controller = false;
public int height=1;
public float generation = 0;
ArrayList<CoilBlockEntity> coils = new ArrayList<>();
public CoilBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
setLazyTickRate(10);
}
@Override
public float maxVoltage() {
return 15000;
}
@Override
public void tick() {
super.tick();
if(!(level.getBlockState(getBlockPos().above()).getBlock() instanceof CoilBlock)) {
controller = true;
}else controller = false;
/////
// if(controller)
// CreateClient.OUTLINER.showAABB(skibidi, reachZone())
// .colored(500)
// .withFaceTextures(AllSpecialTextures.GLUE, AllSpecialTextures.GLUE)
// .disableLineNormals()
// .lineWidth(1 / 16f);
//
// for(BlockPos pos : coils) {
if(getBlockState().getValue(CoilBlock.CAN_EXTRACT)&&!controller)
level.setBlock(getBlockPos(),getBlockState().setValue(CoilBlock.CAN_EXTRACT,false),2);
if(getBlockState().getValue(CoilBlock.CAN_EXTRACT))
return;
if(controller)
for(CoilBlockEntity coil : coils){
if(coil == null)
continue;
if (level.getBlockEntity(coil.getBlockPos()) instanceof CoilBlockEntity be){
if(be.getBlockPos()!=this.getBlockPos()) {
float heightRatio = (float) be.height / height;
if(!be.getBlockState().getValue(CoilBlock.CAN_EXTRACT))
continue;
be.generation = voltage * heightRatio;
if(energy.getEnergyStored()!=0) {
int amount = getForgeEnergy().extractEnergy(transferSpeed()*10, true);
int amount2 = be.getForgeEnergy().receiveEnergy(transferSpeed()*10, true);
getForgeEnergy().extractEnergy(Math.min(amount, amount2), false);
be.getForgeEnergy().receiveEnergy(Math.min(amount, amount2), false);
}
}
}
}
}
@Override
public void lazyTick() {
super.lazyTick();
BlockPos pos = this.getBlockPos().below();
int height = 1;
for(int i = 0; i<4;i++){
if(level.getBlockState(pos).getBlock() instanceof CoilBlock) {
height++;
}else break;
pos = pos.below();
}
this.height = height;
///
coils = new ArrayList<>();
if(controller)
for (BlockPos checkedPos : BlockPos.betweenClosed(new BlockPos(reachZone().minX,reachZone().minY,reachZone().minZ), new BlockPos(reachZone().maxX,reachZone().maxY,reachZone().maxZ))) {
// BlockPos.betweenClosedStream(new BlockPos(reachZone().minX,reachZone().minY,reachZone().minZ), new BlockPos(reachZone().maxX,reachZone().maxY,reachZone().maxZ)
if(level.getBlockEntity(checkedPos) instanceof CoilBlockEntity be&&checkedPos!=getBlockPos()){
if(be.controller)
coils.add((CoilBlockEntity) level.getBlockEntity(checkedPos));
}
//
}
}
public AABB reachZone(){
AABB reach = new AABB(getBlockPos()).inflate((double) height /2);
return reach;
}
@Override
public int voltageGeneration() {
return (int) generation;
}
@Override
public boolean hasElectricitySlot(Direction direction) {
return direction == Direction.UP;
}
}

View File

@@ -0,0 +1,28 @@
package com.drmangotea.createindustry.blocks.electricity.transformer;
import com.simibubi.create.foundation.data.AssetLookup;
import com.simibubi.create.foundation.data.SpecialBlockStateGen;
import com.tterrag.registrate.providers.DataGenContext;
import com.tterrag.registrate.providers.RegistrateBlockstateProvider;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.client.model.generators.ModelFile;
public class CoilGenerator extends SpecialBlockStateGen {
@Override
protected int getXRotation(BlockState state) {
return 0;
}
@Override
protected int getYRotation(BlockState state) {
return 0;
}
public <T extends Block> ModelFile getModel(DataGenContext<Block, T> ctx, RegistrateBlockstateProvider prov, BlockState state) {
return (Boolean)state.getValue(CoilBlock.CAN_EXTRACT) ? AssetLookup.partialBaseModel(ctx, prov, "arrow") : AssetLookup.partialBaseModel(ctx, prov, new String[0]);
}
}

View File

@@ -0,0 +1,67 @@
package com.drmangotea.createindustry.blocks.electricity.voltmeter;
import com.drmangotea.createindustry.blocks.TFMGHorizontalDirectionalBlock;
import com.drmangotea.createindustry.registry.TFMGBlockEntities;
import com.drmangotea.createindustry.registry.TFMGShapes;
import com.simibubi.create.content.equipment.wrench.IWrenchable;
import com.simibubi.create.foundation.block.IBE;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
public class VoltMeterBlock extends TFMGHorizontalDirectionalBlock implements IBE<VoltMeterBlockEntity>, IWrenchable {
public VoltMeterBlock(Properties p_54120_) {
super(p_54120_);
}
@Override
public VoxelShape getShape(BlockState pState, BlockGetter worldIn, BlockPos pos, CollisionContext context) {
return TFMGShapes.VOLTMETER.get(pState.getValue(FACING));
}
@Override
public InteractionResult onWrenched(BlockState state, UseOnContext context) {
Level level = context.getLevel();
BlockPos pos = context.getClickedPos();
Direction direction = context.getClickedFace();
return onBlockEntityUse(level, pos, be -> {
be.range = be.getRange() + 100;
if(be.getRange() > 2000)
be.range = 100;
return InteractionResult.SUCCESS;
});
}
@Override
public Class<VoltMeterBlockEntity> getBlockEntityClass() {
return VoltMeterBlockEntity.class;
}
@Override
public BlockEntityType<? extends VoltMeterBlockEntity> getBlockEntityType() {
return TFMGBlockEntities.VOLTMETER.get();
}
}

View File

@@ -0,0 +1,120 @@
package com.drmangotea.createindustry.blocks.electricity.voltmeter;
import com.drmangotea.createindustry.CreateTFMG;
import com.drmangotea.createindustry.blocks.electricity.base.IElectricBlock;
import com.simibubi.create.content.equipment.goggles.IHaveGoggleInformation;
import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.utility.animation.LerpedFloat;
import net.minecraft.ChatFormatting;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import java.util.List;
import static net.minecraft.world.level.block.HorizontalDirectionalBlock.FACING;
public class VoltMeterBlockEntity extends SmartBlockEntity implements IHaveGoggleInformation {
public LerpedFloat angle = LerpedFloat.angular();
public int voltage=0;
public int range = 500;
public VoltMeterBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
}
@Override
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
}
@Override
public void tick() {
super.tick();
if(!level.isClientSide)
return;
BlockEntity beBehind = level.getBlockEntity(getBlockPos().relative(getBlockState().getValue(FACING).getOpposite()));
if(beBehind instanceof IElectricBlock be){
voltage = Math.min(be.getVoltage(), range );
} else voltage = 0;
float value = (float) Math.abs(voltage) / getRange();
if(value>1)
value = 1;
float targetAngle = Math.abs(value*180);
angle.chase(Math.abs(targetAngle),0.05f, LerpedFloat.Chaser.EXP);
angle.tickChaser();
}
public int getRange(){
return range;
}
@Override
public void write(CompoundTag compound, boolean clientPacket) {
super.write(compound, clientPacket);
compound.putInt("range",range);
compound.putFloat("angle", (float) Math.abs(voltage) / getRange());
}
@Override
protected void read(CompoundTag compound, boolean clientPacket) {
super.read(compound, clientPacket);
range = compound.getInt("range");
angle.setValue(compound.getFloat("angle"));
}
@Override
@SuppressWarnings("removal")
public boolean addToGoggleTooltip(List<Component> tooltip, boolean isPlayerSneaking) {
Lang.translate("goggles.voltmeter")
.style(ChatFormatting.DARK_GRAY)
.forGoggles(tooltip, 1);
Lang.translate("goggles.voltmeter.voltage", Math.min(voltage,range))
.style(ChatFormatting.AQUA)
.forGoggles(tooltip, 1);
Lang.translate("goggles.voltmeter.range", range)
.style(ChatFormatting.DARK_AQUA)
.forGoggles(tooltip, 1);
return true;
}
}

View File

@@ -0,0 +1,59 @@
package com.drmangotea.createindustry.blocks.electricity.voltmeter;
import com.drmangotea.createindustry.CreateTFMG;
import com.drmangotea.createindustry.registry.TFMGPartialModels;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.simibubi.create.foundation.blockEntity.renderer.SafeBlockEntityRenderer;
import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.state.BlockState;
import static net.minecraft.world.level.block.HorizontalDirectionalBlock.FACING;
public class VoltMeterRenderer extends SafeBlockEntityRenderer<VoltMeterBlockEntity> {
public VoltMeterRenderer(BlockEntityRendererProvider.Context context) {}
@Override
protected void renderSafe(VoltMeterBlockEntity be, float partialTicks, PoseStack ms, MultiBufferSource bufferSource, int light, int overlay) {
BlockState blockState = be.getBlockState();
VertexConsumer vb = bufferSource.getBuffer(RenderType.solid());
ms.pushPose();
TransformStack msr = TransformStack.cast(ms);
msr.translate(0.5, 0.5, 0.5);
float dialPivot = 5.75f / 16;
float dialPivot2 = 5.75f / 12;
SuperByteBuffer dial = CachedBufferer.partial(TFMGPartialModels.VOLTMETER_DIAL, blockState);
Direction direction = blockState.getValue(FACING).getCounterClockWise();
if(direction.getAxis() == Direction.Axis.X)
direction = direction.getOpposite();
dial
.rotateY(direction.toYRot())
.unCentre()
.translate(0, dialPivot, dialPivot2)
.rotateX(Math.abs(Math.min( be.angle.getValue(partialTicks),180)))
.translate(0, -dialPivot, -dialPivot2)
.light(light);
dial.renderInto(ms,vb);
ms.popPose();
}
}

View File

@@ -0,0 +1,45 @@
package com.drmangotea.createindustry.blocks.electricity.voltmeter.energy_meter;
import com.drmangotea.createindustry.blocks.TFMGHorizontalDirectionalBlock;
import com.drmangotea.createindustry.registry.TFMGBlockEntities;
import com.drmangotea.createindustry.registry.TFMGShapes;
import com.simibubi.create.content.equipment.wrench.IWrenchable;
import com.simibubi.create.foundation.block.IBE;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
public class EnergyMeterBlock extends TFMGHorizontalDirectionalBlock implements IBE<EnergyMeterBlockEntity>, IWrenchable {
public EnergyMeterBlock(Properties p_54120_) {
super(p_54120_);
}
@Override
public VoxelShape getShape(BlockState pState, BlockGetter worldIn, BlockPos pos, CollisionContext context) {
return TFMGShapes.VOLTMETER.get(pState.getValue(FACING));
}
@Override
public Class<EnergyMeterBlockEntity> getBlockEntityClass() {
return EnergyMeterBlockEntity.class;
}
@Override
public BlockEntityType<? extends EnergyMeterBlockEntity> getBlockEntityType() {
return TFMGBlockEntities.ENERGY_METER.get();
}
}

View File

@@ -0,0 +1,129 @@
package com.drmangotea.createindustry.blocks.electricity.voltmeter.energy_meter;
import com.drmangotea.createindustry.blocks.electricity.base.IElectricBlock;
import com.simibubi.create.content.equipment.goggles.IHaveGoggleInformation;
import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.utility.animation.LerpedFloat;
import net.minecraft.ChatFormatting;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.common.capabilities.ForgeCapabilities;
import net.minecraftforge.energy.EnergyStorage;
import java.util.List;
import static net.minecraft.world.level.block.HorizontalDirectionalBlock.FACING;
public class EnergyMeterBlockEntity extends SmartBlockEntity implements IHaveGoggleInformation {
public LerpedFloat angle = LerpedFloat.angular();
public int energy=0;
public int range = 1;
public EnergyMeterBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
}
@Override
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
}
@Override
public void tick() {
super.tick();
//if(!level.isClientSide)
// return;
Direction direction = getBlockState().getValue(FACING).getOpposite();
BlockEntity beBehind = level.getBlockEntity(getBlockPos().relative(direction));
if(beBehind!=null)
if(beBehind.getCapability(ForgeCapabilities.ENERGY).isPresent()){
energy = beBehind.getCapability(ForgeCapabilities.ENERGY).orElse(new EnergyStorage(0)).getEnergyStored();
range = beBehind.getCapability(ForgeCapabilities.ENERGY).orElse(new EnergyStorage(0)).getMaxEnergyStored();
} else energy = 0;
float value = (float) Math.abs(energy) / getRange();
if(value>1)
value = 1;
float targetAngle = value*180;
angle.chase(targetAngle,0.05f, LerpedFloat.Chaser.EXP);
angle.tickChaser();
}
public int getRange(){
return range;
}
@Override
public void write(CompoundTag compound, boolean clientPacket) {
super.write(compound, clientPacket);
compound.putInt("range",range);
compound.putFloat("angle",(float) Math.abs(energy) / getRange());
}
@Override
protected void read(CompoundTag compound, boolean clientPacket) {
super.read(compound, clientPacket);
range = compound.getInt("range");
angle.setValue(compound.getFloat("angle"));
}
@Override
@SuppressWarnings("removal")
public boolean addToGoggleTooltip(List<Component> tooltip, boolean isPlayerSneaking) {
Lang.translate("goggles.energy_meter")
.style(ChatFormatting.DARK_GRAY)
.forGoggles(tooltip, 1);
Lang.translate("goggles.energy_meter.energy", energy)
.style(ChatFormatting.AQUA)
.forGoggles(tooltip, 1);
Lang.translate("goggles.energy_meter.energy", angle.getValue())
.style(ChatFormatting.AQUA);
return true;
}
}

View File

@@ -0,0 +1,61 @@
package com.drmangotea.createindustry.blocks.electricity.voltmeter.energy_meter;
import com.drmangotea.createindustry.registry.TFMGPartialModels;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.simibubi.create.foundation.blockEntity.renderer.SafeBlockEntityRenderer;
import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.state.BlockState;
import static net.minecraft.world.level.block.HorizontalDirectionalBlock.FACING;
public class EnergyMeterRenderer extends SafeBlockEntityRenderer<EnergyMeterBlockEntity> {
public EnergyMeterRenderer(BlockEntityRendererProvider.Context context) {}
@Override
protected void renderSafe(EnergyMeterBlockEntity be, float partialTicks, PoseStack ms, MultiBufferSource bufferSource, int light, int overlay) {
BlockState blockState = be.getBlockState();
VertexConsumer vb = bufferSource.getBuffer(RenderType.solid());
ms.pushPose();
TransformStack msr = TransformStack.cast(ms);
msr.translate(0.5, 0.5, 0.5);
float dialPivot = 5.75f / 16;
float dialPivot2 = 5.75f / 12;
SuperByteBuffer dial = CachedBufferer.partial(TFMGPartialModels.VOLTMETER_DIAL, blockState);
Direction direction = blockState.getValue(FACING).getCounterClockWise();
if(direction.getAxis() == Direction.Axis.X)
direction = direction.getOpposite();
dial
.rotateY(direction.toYRot())
.unCentre()
.translate(0, dialPivot, dialPivot2)
.rotateX(Math.abs( be.angle.getValue(partialTicks)))
.translate(0, -dialPivot, -dialPivot2)
.light(light);
dial.renderInto(ms,vb);
ms.popPose();
}
}

View File

@@ -0,0 +1,110 @@
package com.drmangotea.createindustry.blocks.engines.low_grade_fuel;
import com.drmangotea.createindustry.registry.TFMGBlockEntities;
import com.drmangotea.createindustry.registry.TFMGShapes;
import com.simibubi.create.content.kinetics.base.DirectionalKineticBlock;
import com.simibubi.create.foundation.block.IBE;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Direction.Axis;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.pathfinder.PathComputationType;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
public class LowGradeFuelEngineBlock extends DirectionalKineticBlock implements IBE<LowGradeFuelEngineBlockEntity> {
public LowGradeFuelEngineBlock(Properties properties) {
super(properties);
}
/*
@Override
public VoxelShape getShape(BlockState state, BlockGetter worldIn, BlockPos pos, CollisionContext context) {
return AllShapes.MOTOR_BLOCK.get(state.getValue(FACING));
}
*/
@Override
public VoxelShape getShape(BlockState pState, BlockGetter worldIn, BlockPos pos, CollisionContext context) {
if(pState.getValue(FACING).getAxis()==Axis.Y) {
return TFMGShapes.COMPACT_ENGINE_VERTICAL.get(pState.getValue(FACING));
}else
return TFMGShapes.COMPACT_ENGINE.get(pState.getValue(FACING));
}
@Override
public BlockState getStateForPlacement(BlockPlaceContext context) {
Direction preferred = getPreferredFacing(context);
if ((context.getPlayer() != null && context.getPlayer()
.isShiftKeyDown()) || preferred == null)
return super.getStateForPlacement(context);
return defaultBlockState()
.setValue(FACING, preferred)
//.setValue(BACK_PART,false)
;
}
// IRotate:
@Override
public boolean hasShaftTowards(LevelReader world, BlockPos pos, BlockState state, Direction face) {
return face == state.getValue(FACING);
}
@Override
public Axis getRotationAxis(BlockState state) {
return state.getValue(FACING)
.getAxis();
}
@Override
public boolean hideStressImpact() {
return true;
}
@Override
public boolean isPathfindable(BlockState state, BlockGetter reader, BlockPos pos, PathComputationType type) {
return false;
}
@Override
public InteractionResult use(BlockState pState, Level level, BlockPos pos, Player pPlayer, InteractionHand pHand, BlockHitResult pHit) {
if (level.getBlockEntity(pos) instanceof LowGradeFuelEngineBlockEntity be)
if (be.playerInteract(pPlayer, pHand))
return InteractionResult.SUCCESS;
return super.use(pState,level,pos,pPlayer,pHand,pHit);
}
@Override
public Class<LowGradeFuelEngineBlockEntity> getBlockEntityClass() {
return LowGradeFuelEngineBlockEntity.class;
}
@Override
public BlockEntityType<? extends LowGradeFuelEngineBlockEntity> getBlockEntityType() {
return TFMGBlockEntities.LOW_GRADE_FUEL_ENGINE.get();
}
}

Some files were not shown because too many files have changed in this diff Show More