Update to 1.20.x

This commit is contained in:
Zontreck 2024-02-28 15:59:48 -07:00
parent 27a3496310
commit 10af6a66f9
43 changed files with 10836 additions and 10572 deletions

View file

@ -11,29 +11,45 @@ package dev.zontreck.engineerdecor;
import dev.zontreck.engineerdecor.blocks.*;
import dev.zontreck.engineerdecor.detail.TreeCutting;
import dev.zontreck.engineerdecor.libmc.Auxiliaries;
import dev.zontreck.engineerdecor.libmc.OptionalRecipeCondition;
import dev.zontreck.engineerdecor.libmc.SlabSliceBlock;
import dev.zontreck.engineerdecor.libmc.VariantSlabBlock;
import dev.zontreck.libzontreck.edlibmc.Auxiliaries;
import dev.zontreck.libzontreck.edlibmc.OptionalRecipeCondition;
import dev.zontreck.libzontreck.edlibmc.SlabSliceBlock;
import dev.zontreck.libzontreck.edlibmc.VariantSlabBlock;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.block.Block;
import net.minecraftforge.common.ForgeConfigSpec;
import org.apache.commons.lang3.tuple.Pair;
import wile.engineersdecor.blocks.*;
import javax.annotation.Nullable;
import java.util.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
public class ModConfig
{
//--------------------------------------------------------------------------------------------------------------------
private static final String MODID = ModEngineersDecor.MODID;
public class ModConfig {
public static final CommonConfig COMMON;
public static final ServerConfig SERVER;
public static final ForgeConfigSpec COMMON_CONFIG_SPEC;
public static final ForgeConfigSpec SERVER_CONFIG_SPEC;
//--------------------------------------------------------------------------------------------------------------------
private static final String MODID = ModEngineersDecor.MODID;
private static final CompoundTag server_config_ = new CompoundTag();
//--------------------------------------------------------------------------------------------------------------------
public static boolean immersiveengineering_installed = false;
//--------------------------------------------------------------------------------------------------------------------
public static boolean without_direct_slab_pickup = false;
//--------------------------------------------------------------------------------------------------------------------
// Optout checks
//--------------------------------------------------------------------------------------------------------------------
public static boolean with_creative_mode_device_drops = false;
private static HashSet<String> optouts_ = new HashSet<>();
private static boolean with_experimental_features_ = false;
private static boolean with_config_logging_ = false;
private static boolean with_debug_logs_ = false;
static {
final Pair<CommonConfig, ForgeConfigSpec> common_ = (new ForgeConfigSpec.Builder()).configure(CommonConfig::new);
@ -44,10 +60,161 @@ public class ModConfig
SERVER = server_.getLeft();
}
//--------------------------------------------------------------------------------------------------------------------
// Cache
//--------------------------------------------------------------------------------------------------------------------
public static class CommonConfig
public static boolean isOptedOut(final @Nullable Block block) {
return (block == null) || isOptedOut(block.asItem());
}
public static boolean isOptedOut(final @Nullable Item item) {
return (item != null) && optouts_.contains(Auxiliaries.getResourceLocation(item).getPath());
}
public static boolean withExperimental() {
return with_experimental_features_;
}
public static boolean withoutRecipes() {
return false;
}
public static boolean withDebug() {
return with_debug_logs_;
}
public static boolean withDebugLogging() {
return with_experimental_features_ && with_config_logging_;
}
public static CompoundTag getServerConfig() // config that may be synchronized from server to client via net pkg.
{
return server_config_;
}
private static void updateOptouts() {
final ArrayList<String> includes = new ArrayList<>();
final ArrayList<String> excludes = new ArrayList<>();
{
String inc = COMMON.pattern_includes.get().toLowerCase().replaceAll(MODID + ":", "").replaceAll("[^*_,a-z\\d]", "");
if (!COMMON.pattern_includes.get().equals(inc)) COMMON.pattern_includes.set(inc);
String[] incl = inc.split(",");
for (int i = 0; i < incl.length; ++i) {
incl[i] = incl[i].replaceAll("[*]", ".*?");
if (!incl[i].isEmpty()) includes.add(incl[i]);
}
}
{
String exc = COMMON.pattern_excludes.get().toLowerCase().replaceAll(MODID + ":", "").replaceAll("[^*_,a-z\\d]", "");
String[] excl = exc.split(",");
for (int i = 0; i < excl.length; ++i) {
excl[i] = excl[i].replaceAll("[*]", ".*?");
if (!excl[i].isEmpty()) excludes.add(excl[i]);
}
}
if (!excludes.isEmpty()) log("Config pattern excludes: '" + String.join(",", excludes) + "'");
if (!includes.isEmpty()) log("Config pattern includes: '" + String.join(",", includes) + "'");
try {
HashSet<String> optouts = new HashSet<>();
ModContent.getRegisteredBlocks().stream().filter((Block block) -> {
if (block == null) return true;
if (block == ModContent.getBlock("sign_decor")) return true;
try {
if (!with_experimental_features_) {
if (block instanceof Auxiliaries.IExperimentalFeature) return true;
}
// Force-include/exclude pattern matching
final String rn = Auxiliaries.getResourceLocation(block).getPath();
try {
for (String e : includes) {
if (rn.matches(e)) {
log("Optout force include: " + rn);
return false;
}
}
for (String e : excludes) {
if (rn.matches(e)) {
log("Optout force exclude: " + rn);
return true;
}
}
} catch (Throwable ex) {
Auxiliaries.logger().error("optout include pattern failed, disabling.");
includes.clear();
excludes.clear();
}
} catch (Exception ex) {
Auxiliaries.logger().error("Exception evaluating the optout config: '" + ex.getMessage() + "'");
}
return false;
}).forEach(
e -> optouts.add(Auxiliaries.getResourceLocation(e).getPath())
);
optouts_ = optouts;
OptionalRecipeCondition.on_config(withExperimental(), withoutRecipes(), ModConfig::isOptedOut, ModConfig::isOptedOut);
} catch (Throwable ex) {
Auxiliaries.logger().error("Exception evaluating the optout config: '" + ex.getMessage() + "'"); // Compat issue: config-apply may be called before the registries are all loaded.
}
}
public static void apply() {
with_config_logging_ = COMMON.with_config_logging.get();
with_experimental_features_ = COMMON.with_experimental.get();
with_debug_logs_ = COMMON.with_debug_logging.get();
if (with_experimental_features_) Auxiliaries.logger().info("Config: EXPERIMENTAL FEATURES ENABLED.");
if (with_debug_logs_)
Auxiliaries.logger().info("Config: DEBUG LOGGING ENABLED, WARNING, THIS MAY SPAM THE LOG.");
immersiveengineering_installed = Auxiliaries.isModLoaded("immersiveengineering");
updateOptouts();
if (!SERVER_CONFIG_SPEC.isLoaded()) return;
without_direct_slab_pickup = SERVER.without_direct_slab_pickup.get();
// -----------------------------------------------------------------------------------------------------------------
EdChair.on_config(SERVER.without_chair_sitting.get(), SERVER.without_mob_chair_sitting.get(), SERVER.chair_mob_sitting_probability_percent.get(), SERVER.chair_mob_standup_probability_percent.get());
EdLadderBlock.on_config(SERVER.without_ladder_speed_boost.get());
VariantSlabBlock.on_config(!SERVER.without_direct_slab_pickup.get());
SlabSliceBlock.on_config(!SERVER.without_direct_slab_pickup.get());
EdFluidBarrel.on_config(12000, 1000);
EdFluidFunnel.on_config(with_experimental_features_);
EdPipeValve.on_config(SERVER.pipevalve_max_flowrate.get(), SERVER.pipevalve_redstone_gain.get());
EdHopper.on_config();
EdDropper.on_config(true);
EdPlacer.on_config();
EdBreaker.on_config(SERVER.block_breaker_power_consumption.get(), SERVER.block_breaker_reluctance.get(), SERVER.block_breaker_min_breaking_time.get(), SERVER.block_breaker_requires_power.get());
EdTreeCutter.on_config(SERVER.tree_cutter_energy_consumption.get(), SERVER.tree_cutter_cutting_time_needed.get(), SERVER.tree_cutter_requires_power.get());
EdFurnace.on_config(SERVER.furnace_smelting_speed_percent.get(), SERVER.furnace_fuel_efficiency_percent.get(), SERVER.furnace_boost_energy_consumption.get(), SERVER.furnace_accepted_heaters.get());
EdElectricalFurnace.on_config(SERVER.e_furnace_speed_percent.get(), SERVER.e_furnace_power_consumption.get(), SERVER.e_furnace_automatic_pulling.get());
EdSolarPanel.on_config(SERVER.small_solar_panel_peak_production.get(), 64000, 1024);
EdMilker.on_config(SERVER.milking_machine_energy_consumption.get(), SERVER.milking_machine_milking_delay.get());
EdFreezer.on_config(144, 2);
EdMineralSmelter.on_config(144, 2);
EdWasteIncinerator.on_config(8);
// -----------------------------------------------------------------------------------------------------------------
{
final List<String> universal_logs = new ArrayList<>(SERVER.tree_cutter_universal_logs.get());
// Fixed known blocks. @todo, also check AE/menril, etc.
universal_logs.add("myrtrees:filled_rubberwood_log");
TreeCutting.on_config(universal_logs);
}
// -----------------------------------------------------------------------------------------------------------------
{
// Check if the config is already synchronized or has to be synchronised.
server_config_.putBoolean("tree_cutter_requires_power", SERVER.tree_cutter_requires_power.get());
server_config_.putBoolean("block_breaker_requires_power", SERVER.block_breaker_requires_power.get());
{
String s = String.join(",", optouts_);
server_config_.putString("optout", s);
if (!s.isEmpty()) log("Opt-outs:" + s);
}
}
}
public static void log(String config_message) {
if (!with_config_logging_) return;
Auxiliaries.logger().info(config_message);
}
public static class CommonConfig {
// Optout
public final ForgeConfigSpec.ConfigValue<String> pattern_excludes;
public final ForgeConfigSpec.ConfigValue<String> pattern_includes;
@ -57,8 +224,7 @@ public class ModConfig
public final ForgeConfigSpec.BooleanValue with_config_logging;
public final ForgeConfigSpec.BooleanValue with_debug_logging;
CommonConfig(ForgeConfigSpec.Builder builder)
{
CommonConfig(ForgeConfigSpec.Builder builder) {
builder.comment("Settings affecting the logical server side.")
.push("server");
// --- OPTOUTS ------------------------------------------------------------
@ -109,10 +275,7 @@ public class ModConfig
}
}
//--------------------------------------------------------------------------------------------------------------------
public static class ServerConfig
{
public static class ServerConfig {
// Optout
public final ForgeConfigSpec.BooleanValue without_chair_sitting;
public final ForgeConfigSpec.BooleanValue without_mob_chair_sitting;
@ -145,8 +308,7 @@ public class ModConfig
public final ForgeConfigSpec.IntValue milking_machine_energy_consumption;
public final ForgeConfigSpec.IntValue milking_machine_milking_delay;
ServerConfig(ForgeConfigSpec.Builder builder)
{
ServerConfig(ForgeConfigSpec.Builder builder) {
builder.comment("Settings affecting the logical server side.")
.push("server");
// --- OPTOUTS ------------------------------------------------------------
@ -322,165 +484,4 @@ public class ModConfig
}
}
//--------------------------------------------------------------------------------------------------------------------
// Optout checks
//--------------------------------------------------------------------------------------------------------------------
public static boolean isOptedOut(final @Nullable Block block)
{ return (block==null) || isOptedOut(block.asItem()); }
public static boolean isOptedOut(final @Nullable Item item)
{ return (item!=null) && optouts_.contains(Auxiliaries.getResourceLocation(item).getPath()); }
public static boolean withExperimental()
{ return with_experimental_features_; }
public static boolean withoutRecipes()
{ return false; }
public static boolean withDebug()
{ return with_debug_logs_; }
public static boolean withDebugLogging()
{ return with_experimental_features_ && with_config_logging_; }
//--------------------------------------------------------------------------------------------------------------------
// Cache
//--------------------------------------------------------------------------------------------------------------------
private static final CompoundTag server_config_ = new CompoundTag();
private static HashSet<String> optouts_ = new HashSet<>();
private static boolean with_experimental_features_ = false;
private static boolean with_config_logging_ = false;
private static boolean with_debug_logs_ = false;
public static boolean immersiveengineering_installed = false;
public static boolean without_direct_slab_pickup = false;
public static boolean with_creative_mode_device_drops = false;
public static CompoundTag getServerConfig() // config that may be synchronized from server to client via net pkg.
{ return server_config_; }
private static void updateOptouts()
{
final ArrayList<String> includes = new ArrayList<>();
final ArrayList<String> excludes = new ArrayList<>();
{
String inc = COMMON.pattern_includes.get().toLowerCase().replaceAll(MODID+":", "").replaceAll("[^*_,a-z\\d]", "");
if(!COMMON.pattern_includes.get().equals(inc)) COMMON.pattern_includes.set(inc);
String[] incl = inc.split(",");
for(int i=0; i< incl.length; ++i) {
incl[i] = incl[i].replaceAll("[*]", ".*?");
if(!incl[i].isEmpty()) includes.add(incl[i]);
}
}
{
String exc = COMMON.pattern_excludes.get().toLowerCase().replaceAll(MODID+":", "").replaceAll("[^*_,a-z\\d]", "");
String[] excl = exc.split(",");
for(int i=0; i< excl.length; ++i) {
excl[i] = excl[i].replaceAll("[*]", ".*?");
if(!excl[i].isEmpty()) excludes.add(excl[i]);
}
}
if(!excludes.isEmpty()) log("Config pattern excludes: '" + String.join(",", excludes) + "'");
if(!includes.isEmpty()) log("Config pattern includes: '" + String.join(",", includes) + "'");
try {
HashSet<String> optouts = new HashSet<>();
ModContent.getRegisteredBlocks().stream().filter((Block block) -> {
if(block==null) return true;
if(block==ModContent.getBlock("sign_decor")) return true;
try {
if(!with_experimental_features_) {
if(block instanceof Auxiliaries.IExperimentalFeature) return true;
}
// Force-include/exclude pattern matching
final String rn = Auxiliaries.getResourceLocation(block).getPath();
try {
for(String e : includes) {
if(rn.matches(e)) {
log("Optout force include: "+rn);
return false;
}
}
for(String e : excludes) {
if(rn.matches(e)) {
log("Optout force exclude: "+rn);
return true;
}
}
} catch(Throwable ex) {
Auxiliaries.logger().error("optout include pattern failed, disabling.");
includes.clear();
excludes.clear();
}
} catch(Exception ex) {
Auxiliaries.logger().error("Exception evaluating the optout config: '"+ex.getMessage()+"'");
}
return false;
}).forEach(
e -> optouts.add(Auxiliaries.getResourceLocation(e).getPath())
);
optouts_ = optouts;
OptionalRecipeCondition.on_config(withExperimental(), withoutRecipes(), ModConfig::isOptedOut, ModConfig::isOptedOut);
} catch(Throwable ex) {
Auxiliaries.logger().error("Exception evaluating the optout config: '"+ex.getMessage()+"'"); // Compat issue: config-apply may be called before the registries are all loaded.
}
}
public static void apply()
{
with_config_logging_ = COMMON.with_config_logging.get();
with_experimental_features_ = COMMON.with_experimental.get();
with_debug_logs_ = COMMON.with_debug_logging.get();
if(with_experimental_features_) Auxiliaries.logger().info("Config: EXPERIMENTAL FEATURES ENABLED.");
if(with_debug_logs_) Auxiliaries.logger().info("Config: DEBUG LOGGING ENABLED, WARNING, THIS MAY SPAM THE LOG.");
immersiveengineering_installed = Auxiliaries.isModLoaded("immersiveengineering");
updateOptouts();
if(!SERVER_CONFIG_SPEC.isLoaded()) return;
without_direct_slab_pickup = SERVER.without_direct_slab_pickup.get();
// -----------------------------------------------------------------------------------------------------------------
EdChair.on_config(SERVER.without_chair_sitting.get(), SERVER.without_mob_chair_sitting.get(), SERVER.chair_mob_sitting_probability_percent.get(), SERVER.chair_mob_standup_probability_percent.get());
EdLadderBlock.on_config(SERVER.without_ladder_speed_boost.get());
VariantSlabBlock.on_config(!SERVER.without_direct_slab_pickup.get());
SlabSliceBlock.on_config(!SERVER.without_direct_slab_pickup.get());
EdFluidBarrel.on_config(12000, 1000);
EdFluidFunnel.on_config(with_experimental_features_);
EdPipeValve.on_config(SERVER.pipevalve_max_flowrate.get(), SERVER.pipevalve_redstone_gain.get());
EdHopper.on_config();
EdDropper.on_config(true);
EdPlacer.on_config();
EdBreaker.on_config(SERVER.block_breaker_power_consumption.get(), SERVER.block_breaker_reluctance.get(), SERVER.block_breaker_min_breaking_time.get(), SERVER.block_breaker_requires_power.get());
EdTreeCutter.on_config(SERVER.tree_cutter_energy_consumption.get(), SERVER.tree_cutter_cutting_time_needed.get(), SERVER.tree_cutter_requires_power.get());
EdFurnace.on_config(SERVER.furnace_smelting_speed_percent.get(), SERVER.furnace_fuel_efficiency_percent.get(), SERVER.furnace_boost_energy_consumption.get(), SERVER.furnace_accepted_heaters.get());
EdElectricalFurnace.on_config(SERVER.e_furnace_speed_percent.get(), SERVER.e_furnace_power_consumption.get(), SERVER.e_furnace_automatic_pulling.get());
EdSolarPanel.on_config(SERVER.small_solar_panel_peak_production.get(), 64000, 1024);
EdMilker.on_config(SERVER.milking_machine_energy_consumption.get(), SERVER.milking_machine_milking_delay.get());
EdFreezer.on_config(144, 2);
EdMineralSmelter.on_config(144, 2);
EdWasteIncinerator.on_config(8);
// -----------------------------------------------------------------------------------------------------------------
{
final List<String> universal_logs = new ArrayList<>(SERVER.tree_cutter_universal_logs.get());
// Fixed known blocks. @todo, also check AE/menril, etc.
universal_logs.add("myrtrees:filled_rubberwood_log");
TreeCutting.on_config(universal_logs);
}
// -----------------------------------------------------------------------------------------------------------------
{
// Check if the config is already synchronized or has to be synchronised.
server_config_.putBoolean("tree_cutter_requires_power", SERVER.tree_cutter_requires_power.get());
server_config_.putBoolean("block_breaker_requires_power", SERVER.block_breaker_requires_power.get());
{
String s = String.join(",", optouts_);
server_config_.putString("optout", s);
if(!s.isEmpty()) log("Opt-outs:" + s);
}
}
}
public static void log(String config_message)
{
if(!with_config_logging_) return;
Auxiliaries.logger().info(config_message);
}
}

View file

@ -15,7 +15,7 @@ package dev.zontreck.engineerdecor;
import dev.zontreck.engineerdecor.blocks.*;
import dev.zontreck.engineerdecor.detail.ModRenderers;
import dev.zontreck.engineerdecor.items.EdItem;
import dev.zontreck.engineerdecor.libmc.*;
import dev.zontreck.libzontreck.edlibmc.*;
import net.minecraft.client.gui.screens.MenuScreens;
import net.minecraft.client.renderer.entity.EntityRenderers;
import net.minecraft.core.BlockPos;
@ -33,8 +33,6 @@ import net.minecraft.world.level.block.SoundType;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Material;
import net.minecraft.world.level.material.MaterialColor;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.shapes.BooleanOp;
import net.minecraft.world.phys.shapes.Shapes;
@ -42,8 +40,6 @@ import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import wile.engineersdecor.blocks.*;
import wile.engineersdecor.libmc.*;
import javax.annotation.Nonnull;
import java.util.ArrayList;
@ -52,15 +48,8 @@ import java.util.List;
@SuppressWarnings("unused")
public class ModContent
{
private static class detail {
public static String MODID = "";
public static Boolean disallowSpawn(BlockState state, BlockGetter reader, BlockPos pos, EntityType<?> entity) { return false; }
}
public static void init(String modid)
{
public class ModContent {
public static void init(String modid) {
detail.MODID = modid;
initTags();
initBlocks();
@ -68,46 +57,44 @@ public class ModContent
initEntities();
}
public static void initTags()
{
public static void initTags() {
Registries.addOptionalBlockTag("accepted_mineral_smelter_input", new ResourceLocation("minecraft", "diorite"), new ResourceLocation("minecraft", "cobblestone"));
}
public static void initBlocks()
{
public static void initBlocks() {
Registries.addBlock("clinker_brick_block", () -> new StandardBlocks.BaseBlock(
StandardBlocks.CFG_DEFAULT,
BlockBehaviour.Properties.of(Material.STONE, MaterialColor.STONE).strength(0.5f, 7f).sound(SoundType.STONE)
BlockBehaviour.Properties.of().strength(0.5f, 7f).sound(SoundType.STONE)
));
Registries.addBlock("clinker_brick_slab", () -> new VariantSlabBlock(
StandardBlocks.CFG_DEFAULT,
BlockBehaviour.Properties.of(Material.STONE, MaterialColor.STONE).strength(0.5f, 7f).sound(SoundType.STONE)
BlockBehaviour.Properties.of().strength(0.5f, 7f).sound(SoundType.STONE)
));
Registries.addBlock("clinker_brick_stairs", () -> new StandardStairsBlock(
StandardBlocks.CFG_DEFAULT,
() -> Registries.getBlock("clinker_brick_block").defaultBlockState(),
BlockBehaviour.Properties.of(Material.STONE, MaterialColor.STONE).strength(0.5f, 7f).sound(SoundType.STONE)
BlockBehaviour.Properties.of().strength(0.5f, 7f).sound(SoundType.STONE)
));
Registries.addBlock("clinker_brick_wall", () -> new EdWallBlock(
StandardBlocks.CFG_DEFAULT,
BlockBehaviour.Properties.of(Material.STONE, MaterialColor.STONE).strength(0.5f, 7f).sound(SoundType.STONE)
BlockBehaviour.Properties.of().strength(0.5f, 7f).sound(SoundType.STONE)
));
Registries.addBlock("clinker_brick_stained_block", () -> new StandardBlocks.BaseBlock(
StandardBlocks.CFG_DEFAULT,
BlockBehaviour.Properties.of(Material.STONE, MaterialColor.STONE).strength(0.5f, 7f).sound(SoundType.STONE)
BlockBehaviour.Properties.of().strength(0.5f, 7f).sound(SoundType.STONE)
));
Registries.addBlock("clinker_brick_stained_slab", () -> new VariantSlabBlock(
StandardBlocks.CFG_DEFAULT,
BlockBehaviour.Properties.of(Material.STONE, MaterialColor.STONE).strength(0.5f, 7f).sound(SoundType.STONE)
BlockBehaviour.Properties.of().strength(0.5f, 7f).sound(SoundType.STONE)
));
Registries.addBlock("clinker_brick_stained_stairs", () -> new StandardStairsBlock(
StandardBlocks.CFG_DEFAULT,
() -> Registries.getBlock("clinker_brick_stained_block").defaultBlockState(),
BlockBehaviour.Properties.of(Material.STONE, MaterialColor.STONE).strength(0.5f, 7f).sound(SoundType.STONE)
BlockBehaviour.Properties.of().strength(0.5f, 7f).sound(SoundType.STONE)
));
Registries.addBlock("clinker_brick_sastor_corner_block", () -> new EdCornerOrnamentedBlock(
StandardBlocks.CFG_DEFAULT,
BlockBehaviour.Properties.of(Material.STONE, MaterialColor.STONE).strength(0.5f, 7f).sound(SoundType.STONE),
BlockBehaviour.Properties.of().strength(0.5f, 7f).sound(SoundType.STONE),
new Block[]{
Registries.getBlock("clinker_brick_block"),
Registries.getBlock("clinker_brick_slab"),
@ -119,7 +106,7 @@ public class ModContent
));
Registries.addBlock("clinker_brick_recessed", () -> new StandardBlocks.HorizontalWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_LOOK_PLACEMENT,
BlockBehaviour.Properties.of(Material.STONE, MaterialColor.STONE).strength(0.5f, 7f).sound(SoundType.STONE),
BlockBehaviour.Properties.of().strength(0.5f, 7f).sound(SoundType.STONE),
new AABB[]{
Auxiliaries.getPixeledAABB(3, 0, 0, 13, 16, 1),
Auxiliaries.getPixeledAABB(0, 0, 1, 16, 16, 11),
@ -128,7 +115,7 @@ public class ModContent
));
Registries.addBlock("clinker_brick_vertically_slit", () -> new StandardBlocks.HorizontalWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_LOOK_PLACEMENT,
BlockBehaviour.Properties.of(Material.STONE, MaterialColor.STONE).strength(0.5f, 7f).sound(SoundType.STONE),
BlockBehaviour.Properties.of().strength(0.5f, 7f).sound(SoundType.STONE),
new AABB[]{
Auxiliaries.getPixeledAABB(3, 0, 0, 13, 16, 1),
Auxiliaries.getPixeledAABB(3, 0, 15, 13, 16, 16),
@ -137,7 +124,7 @@ public class ModContent
));
Registries.addBlock("clinker_brick_vertical_slab_structured", () -> new StandardBlocks.HorizontalWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_LOOK_PLACEMENT,
BlockBehaviour.Properties.of(Material.STONE, MaterialColor.STONE).strength(0.5f, 7f).sound(SoundType.STONE),
BlockBehaviour.Properties.of().strength(0.5f, 7f).sound(SoundType.STONE),
new AABB[]{
Auxiliaries.getPixeledAABB(0, 0, 0, 16, 16, 8),
}
@ -147,96 +134,96 @@ public class ModContent
Registries.addBlock("slag_brick_block", () -> new StandardBlocks.BaseBlock(
StandardBlocks.CFG_DEFAULT,
BlockBehaviour.Properties.of(Material.STONE, MaterialColor.STONE).strength(0.5f, 7f).sound(SoundType.STONE)
BlockBehaviour.Properties.of().strength(0.5f, 7f).sound(SoundType.STONE)
));
Registries.addBlock("slag_brick_slab", () -> new VariantSlabBlock(
StandardBlocks.CFG_DEFAULT,
BlockBehaviour.Properties.of(Material.STONE, MaterialColor.STONE).strength(0.5f, 7f).sound(SoundType.STONE)
BlockBehaviour.Properties.of().strength(0.5f, 7f).sound(SoundType.STONE)
));
Registries.addBlock("slag_brick_stairs", () -> new StandardStairsBlock(
StandardBlocks.CFG_DEFAULT,
() -> Registries.getBlock("slag_brick_block").defaultBlockState(),
BlockBehaviour.Properties.of(Material.STONE, MaterialColor.STONE).strength(0.5f, 7f).sound(SoundType.STONE)
BlockBehaviour.Properties.of().strength(0.5f, 7f).sound(SoundType.STONE)
));
Registries.addBlock("slag_brick_wall", () -> new EdWallBlock(
StandardBlocks.CFG_DEFAULT,
BlockBehaviour.Properties.of(Material.STONE, MaterialColor.STONE).strength(0.5f, 7f).sound(SoundType.STONE)
BlockBehaviour.Properties.of().strength(0.5f, 7f).sound(SoundType.STONE)
));
// -------------------------------------------------------------------------------------------------------------------
Registries.addBlock("rebar_concrete", () -> new StandardBlocks.BaseBlock(
StandardBlocks.CFG_DEFAULT,
BlockBehaviour.Properties.of(Material.STONE, MaterialColor.STONE).strength(1.0f, 2000f).sound(SoundType.STONE).isValidSpawn(detail::disallowSpawn)
BlockBehaviour.Properties.of().strength(1.0f, 2000f).sound(SoundType.STONE).isValidSpawn(detail::disallowSpawn)
));
Registries.addBlock("rebar_concrete_slab", () -> new VariantSlabBlock(
StandardBlocks.CFG_DEFAULT,
BlockBehaviour.Properties.of(Material.STONE, MaterialColor.STONE).strength(1.0f, 2000f).sound(SoundType.STONE).isValidSpawn(detail::disallowSpawn)
BlockBehaviour.Properties.of().strength(1.0f, 2000f).sound(SoundType.STONE).isValidSpawn(detail::disallowSpawn)
));
Registries.addBlock("rebar_concrete_stairs", () -> new StandardStairsBlock(
StandardBlocks.CFG_DEFAULT,
() -> Registries.getBlock("rebar_concrete").defaultBlockState(),
BlockBehaviour.Properties.of(Material.STONE, MaterialColor.STONE).strength(1.0f, 2000f).sound(SoundType.STONE).isValidSpawn(detail::disallowSpawn)
BlockBehaviour.Properties.of().strength(1.0f, 2000f).sound(SoundType.STONE).isValidSpawn(detail::disallowSpawn)
));
Registries.addBlock("rebar_concrete_wall", () -> new EdWallBlock(
StandardBlocks.CFG_DEFAULT,
BlockBehaviour.Properties.of(Material.STONE, MaterialColor.STONE).strength(1.0f, 2000f).sound(SoundType.STONE).isValidSpawn(detail::disallowSpawn)
BlockBehaviour.Properties.of().strength(1.0f, 2000f).sound(SoundType.STONE).isValidSpawn(detail::disallowSpawn)
));
Registries.addBlock("halfslab_rebar_concrete", () -> new SlabSliceBlock(
StandardBlocks.CFG_CUTOUT,
BlockBehaviour.Properties.of(Material.STONE, MaterialColor.STONE).strength(1.0f, 2000f).sound(SoundType.STONE).isValidSpawn(detail::disallowSpawn)
BlockBehaviour.Properties.of().strength(1.0f, 2000f).sound(SoundType.STONE).isValidSpawn(detail::disallowSpawn)
));
// -------------------------------------------------------------------------------------------------------------------
Registries.addBlock("rebar_concrete_tile", () -> new StandardBlocks.BaseBlock(
StandardBlocks.CFG_DEFAULT,
BlockBehaviour.Properties.of(Material.STONE, MaterialColor.STONE).strength(1.0f, 2000f).sound(SoundType.STONE).isValidSpawn(detail::disallowSpawn)
BlockBehaviour.Properties.of().strength(1.0f, 2000f).sound(SoundType.STONE).isValidSpawn(detail::disallowSpawn)
));
Registries.addBlock("rebar_concrete_tile_slab", () -> new VariantSlabBlock(
StandardBlocks.CFG_DEFAULT,
BlockBehaviour.Properties.of(Material.STONE, MaterialColor.STONE).strength(1.0f, 2000f).sound(SoundType.STONE).isValidSpawn(detail::disallowSpawn)
BlockBehaviour.Properties.of().strength(1.0f, 2000f).sound(SoundType.STONE).isValidSpawn(detail::disallowSpawn)
));
Registries.addBlock("rebar_concrete_tile_stairs", () -> new StandardStairsBlock(
StandardBlocks.CFG_DEFAULT,
() -> Registries.getBlock("rebar_concrete_tile").defaultBlockState(),
BlockBehaviour.Properties.of(Material.STONE, MaterialColor.STONE).strength(1.0f, 2000f).sound(SoundType.STONE).isValidSpawn(detail::disallowSpawn)
BlockBehaviour.Properties.of().strength(1.0f, 2000f).sound(SoundType.STONE).isValidSpawn(detail::disallowSpawn)
));
// -------------------------------------------------------------------------------------------------------------------
Registries.addBlock("panzerglass_block", () -> new EdGlassBlock(
StandardBlocks.CFG_TRANSLUCENT,
BlockBehaviour.Properties.of(Material.GLASS, MaterialColor.NONE).strength(0.5f, 2000f).sound(SoundType.METAL).noOcclusion().isValidSpawn(detail::disallowSpawn)
BlockBehaviour.Properties.of().strength(0.5f, 2000f).sound(SoundType.METAL).noOcclusion().isValidSpawn(detail::disallowSpawn)
));
Registries.addBlock("panzerglass_slab", () -> new VariantSlabBlock(
StandardBlocks.CFG_TRANSLUCENT,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.5f, 2000f).sound(SoundType.METAL).noOcclusion().isValidSpawn(detail::disallowSpawn)
BlockBehaviour.Properties.of().strength(0.5f, 2000f).sound(SoundType.METAL).noOcclusion().isValidSpawn(detail::disallowSpawn)
));
// -------------------------------------------------------------------------------------------------------------------
Registries.addBlock("dark_shingle_roof", () -> new EdRoofBlock(
StandardBlocks.CFG_CUTOUT,
BlockBehaviour.Properties.of(Material.STONE, MaterialColor.STONE).strength(0.5f, 6f).sound(SoundType.STONE).noOcclusion().dynamicShape().isValidSpawn(detail::disallowSpawn)
BlockBehaviour.Properties.of().strength(0.5f, 6f).sound(SoundType.STONE).noOcclusion().dynamicShape().isValidSpawn(detail::disallowSpawn)
));
Registries.addBlock("dark_shingle_roof_metallized", () -> new EdRoofBlock(
StandardBlocks.CFG_CUTOUT,
BlockBehaviour.Properties.of(Material.STONE, MaterialColor.STONE).strength(0.5f, 6f).sound(SoundType.STONE).noOcclusion().dynamicShape().isValidSpawn(detail::disallowSpawn)
BlockBehaviour.Properties.of().strength(0.5f, 6f).sound(SoundType.STONE).noOcclusion().dynamicShape().isValidSpawn(detail::disallowSpawn)
));
Registries.addBlock("dark_shingle_roof_skylight", () -> new EdRoofBlock(
StandardBlocks.CFG_TRANSLUCENT,
BlockBehaviour.Properties.of(Material.STONE, MaterialColor.STONE).strength(0.5f, 6f).sound(SoundType.STONE).noOcclusion().dynamicShape().isValidSpawn(detail::disallowSpawn)
BlockBehaviour.Properties.of().strength(0.5f, 6f).sound(SoundType.STONE).noOcclusion().dynamicShape().isValidSpawn(detail::disallowSpawn)
));
Registries.addBlock("dark_shingle_roof_chimneytrunk", () -> new EdChimneyTrunkBlock(
StandardBlocks.CFG_CUTOUT,
BlockBehaviour.Properties.of(Material.STONE, MaterialColor.STONE).strength(0.5f, 6f).sound(SoundType.STONE).noOcclusion().dynamicShape().isValidSpawn(detail::disallowSpawn),
BlockBehaviour.Properties.of().strength(0.5f, 6f).sound(SoundType.STONE).noOcclusion().dynamicShape().isValidSpawn(detail::disallowSpawn),
Shapes.create(Auxiliaries.getPixeledAABB(3, 0, 3, 13, 16, 13)),
Shapes.create(Auxiliaries.getPixeledAABB(5, 0, 5, 11, 16, 11))
));
Registries.addBlock("dark_shingle_roof_wireconduit", () -> new EdChimneyTrunkBlock(
StandardBlocks.CFG_CUTOUT,
BlockBehaviour.Properties.of(Material.STONE, MaterialColor.STONE).strength(0.5f, 6f).sound(SoundType.STONE).noOcclusion().dynamicShape().isValidSpawn(detail::disallowSpawn),
BlockBehaviour.Properties.of().strength(0.5f, 6f).sound(SoundType.STONE).noOcclusion().dynamicShape().isValidSpawn(detail::disallowSpawn),
Shapes.join(
Shapes.create(Auxiliaries.getPixeledAABB(3, 0, 3, 13, 13, 13)),
Shapes.create(Auxiliaries.getPixeledAABB(5, 13, 5, 11, 16, 11)),
@ -250,46 +237,46 @@ public class ModContent
));
Registries.addBlock("dark_shingle_roof_chimney", () -> new EdChimneyBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_AI_PASSABLE,
BlockBehaviour.Properties.of(Material.STONE, MaterialColor.STONE).strength(0.5f, 6f).sound(SoundType.STONE).dynamicShape().isValidSpawn(detail::disallowSpawn),
BlockBehaviour.Properties.of().strength(0.5f, 6f).sound(SoundType.STONE).dynamicShape().isValidSpawn(detail::disallowSpawn),
Auxiliaries.getPixeledAABB(3, 0, 3, 13, 6, 13)
));
Registries.addBlock("dark_shingle_roof_block", () -> new StandardBlocks.BaseBlock(
StandardBlocks.CFG_DEFAULT,
BlockBehaviour.Properties.of(Material.STONE, MaterialColor.STONE).strength(0.5f, 6f).sound(SoundType.STONE)
BlockBehaviour.Properties.of().strength(0.5f, 6f).sound(SoundType.STONE)
));
Registries.addBlock("dark_shingle_roof_slab", () -> new VariantSlabBlock(
StandardBlocks.CFG_DEFAULT,
BlockBehaviour.Properties.of(Material.STONE, MaterialColor.STONE).strength(0.5f, 6f).sound(SoundType.STONE)
BlockBehaviour.Properties.of().strength(0.5f, 6f).sound(SoundType.STONE)
));
// -------------------------------------------------------------------------------------------------------------------
Registries.addBlock("dense_grit_sand_block", () -> new StandardBlocks.BaseBlock(
StandardBlocks.CFG_DEFAULT,
BlockBehaviour.Properties.of(Material.DIRT, MaterialColor.DIRT).strength(0.1f, 3f).sound(SoundType.GRAVEL)
BlockBehaviour.Properties.of().strength(0.1f, 3f).sound(SoundType.GRAVEL)
));
Registries.addBlock("dense_grit_dirt_block", () -> new StandardBlocks.BaseBlock(
StandardBlocks.CFG_DEFAULT,
BlockBehaviour.Properties.of(Material.DIRT, MaterialColor.DIRT).strength(0.1f, 3f).sound(SoundType.GRAVEL)
BlockBehaviour.Properties.of().strength(0.1f, 3f).sound(SoundType.GRAVEL)
));
Registries.addBlock("dark_shingle_roof_slabslice", () -> new SlabSliceBlock(
StandardBlocks.CFG_DEFAULT,
BlockBehaviour.Properties.of(Material.STONE, MaterialColor.STONE).strength(0.5f, 6f).sound(SoundType.STONE)
BlockBehaviour.Properties.of().strength(0.5f, 6f).sound(SoundType.STONE)
));
// -------------------------------------------------------------------------------------------------------------------
Registries.addBlock("metal_rung_ladder", () -> new EdLadderBlock(
StandardBlocks.CFG_DEFAULT,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.3f, 8f).sound(SoundType.METAL).noOcclusion()
BlockBehaviour.Properties.of().strength(0.3f, 8f).sound(SoundType.METAL).noOcclusion()
));
Registries.addBlock("metal_rung_steps", () -> new EdLadderBlock(
StandardBlocks.CFG_DEFAULT,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.3f, 8f).sound(SoundType.METAL).noOcclusion()
BlockBehaviour.Properties.of().strength(0.3f, 8f).sound(SoundType.METAL).noOcclusion()
));
Registries.addBlock("iron_hatch", () -> new EdHatchBlock(
StandardBlocks.CFG_LOOK_PLACEMENT,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.3f, 2000f).sound(SoundType.METAL),
BlockBehaviour.Properties.of().strength(0.3f, 2000f).sound(SoundType.METAL),
new AABB[]{Auxiliaries.getPixeledAABB(0, 0, 0, 16, 3, 16)},
new AABB[]{
Auxiliaries.getPixeledAABB(0, 0, 0, 16, 16, 3),
@ -300,56 +287,38 @@ public class ModContent
));
Registries.addBlock("metal_sliding_door", () -> new StandardDoorBlock(
StandardBlocks.CFG_TRANSLUCENT | StandardBlocks.CFG_HORIZIONTAL,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.5f, 8f).sound(SoundType.METAL).noOcclusion(),
new AABB[]{
Auxiliaries.getPixeledAABB(15, 0.0,6, 16,16.0,10),
Auxiliaries.getPixeledAABB( 0,15.5,6, 16,16.0,10),
},
new AABB[]{
Auxiliaries.getPixeledAABB(15, 0.0,6, 16,16.0,10),
Auxiliaries.getPixeledAABB( 0, 0.0,6, 16, 0.3,10),
},
new AABB[]{
Auxiliaries.getPixeledAABB( 0,0,7, 16,16,9)
},
new AABB[]{
Auxiliaries.getPixeledAABB( 0,0,7, 16,16,9)
},
SoundEvents.IRON_DOOR_OPEN, SoundEvents.IRON_DOOR_CLOSE
BlockBehaviour.Properties.of().strength(0.5f, 8f).sound(SoundType.METAL).noOcclusion()
));
// -------------------------------------------------------------------------------------------------------------------
Registries.addBlock("old_industrial_wood_planks", () -> new StandardBlocks.BaseBlock(
StandardBlocks.CFG_DEFAULT,
BlockBehaviour.Properties.of(Material.WOOD, MaterialColor.WOOD).strength(0.5f, 6f).sound(SoundType.WOOD)
BlockBehaviour.Properties.of().strength(0.5f, 6f).sound(SoundType.WOOD)
));
Registries.addBlock("old_industrial_wood_slab", () -> new VariantSlabBlock(
StandardBlocks.CFG_DEFAULT,
BlockBehaviour.Properties.of(Material.WOOD, MaterialColor.WOOD).strength(0.5f, 6f).sound(SoundType.WOOD)
BlockBehaviour.Properties.of().strength(0.5f, 6f).sound(SoundType.WOOD)
));
Registries.addBlock("old_industrial_wood_stairs", () -> new StandardStairsBlock(
StandardBlocks.CFG_DEFAULT,
() -> Registries.getBlock("old_industrial_wood_planks").defaultBlockState(),
BlockBehaviour.Properties.of(Material.WOOD, MaterialColor.WOOD).strength(0.5f, 6f).sound(SoundType.WOOD)
BlockBehaviour.Properties.of().strength(0.5f, 6f).sound(SoundType.WOOD)
));
Registries.addBlock("old_industrial_wood_slabslice", () -> new SlabSliceBlock(
StandardBlocks.CFG_CUTOUT,
BlockBehaviour.Properties.of(Material.WOOD, MaterialColor.WOOD).strength(0.5f, 6f).sound(SoundType.WOOD).noOcclusion()
BlockBehaviour.Properties.of().strength(0.5f, 6f).sound(SoundType.WOOD).noOcclusion()
));
Registries.addBlock("old_industrial_wood_door", () -> new StandardDoorBlock(
StandardBlocks.CFG_DEFAULT,
BlockBehaviour.Properties.of(Material.WOOD, MaterialColor.WOOD).strength(0.5f, 6f).sound(SoundType.WOOD).noOcclusion(),
Auxiliaries.getPixeledAABB(15,0, 0, 16,16,16),
Auxiliaries.getPixeledAABB( 0,0,13, 16,16,16),
SoundEvents.WOODEN_DOOR_OPEN, SoundEvents.WOODEN_DOOR_CLOSE
BlockBehaviour.Properties.of().strength(0.5f, 6f).sound(SoundType.WOOD).noOcclusion()
));
// -------------------------------------------------------------------------------------------------------------------
Registries.addBlock("treated_wood_stool", () -> new EdChair.ChairBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_LOOK_PLACEMENT,
BlockBehaviour.Properties.of(Material.WOOD, MaterialColor.WOOD).strength(0.5f, 5f).sound(SoundType.WOOD).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.5f, 5f).sound(SoundType.WOOD).noOcclusion(),
new AABB[]{
Auxiliaries.getPixeledAABB(4, 7, 4, 12, 8.8, 12),
Auxiliaries.getPixeledAABB(7, 0, 7, 9, 7, 9),
@ -362,7 +331,7 @@ public class ModContent
Registries.addBlock("iron_inset_light", () -> new StandardBlocks.DirectedWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_OPPOSITE_PLACEMENT | StandardBlocks.CFG_AI_PASSABLE,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.5f, 8f).sound(SoundType.METAL).lightLevel((state)->15).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.5f, 8f).sound(SoundType.METAL).lightLevel((state) -> 15).noOcclusion(),
new AABB[]{
Auxiliaries.getPixeledAABB(5, 7, 0, 11, 9, 0.375),
Auxiliaries.getPixeledAABB(6, 6, 0, 10, 10, 0.375),
@ -371,12 +340,12 @@ public class ModContent
));
Registries.addBlock("iron_floor_edge_light", () -> new StandardBlocks.DirectedWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_LOOK_PLACEMENT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_AI_PASSABLE,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.5f, 8f).sound(SoundType.METAL).lightLevel((state)->15).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.5f, 8f).sound(SoundType.METAL).lightLevel((state) -> 15).noOcclusion(),
Auxiliaries.getPixeledAABB(5, 0, 0, 11, 1.8125, 0.375)
));
Registries.addBlock("iron_ceiling_edge_light", () -> new StandardBlocks.DirectedWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_LOOK_PLACEMENT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_AI_PASSABLE,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.5f, 8f).sound(SoundType.METAL).lightLevel((state)->15).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.5f, 8f).sound(SoundType.METAL).lightLevel((state) -> 15).noOcclusion(),
new AABB[]{
Auxiliaries.getPixeledAABB(0, 15.5, 0, 16, 16, 2.0),
Auxiliaries.getPixeledAABB(0, 14.0, 0, 16, 16, 0.5),
@ -386,7 +355,7 @@ public class ModContent
));
Registries.addBlock("iron_bulb_light", () -> new StandardBlocks.DirectedWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_OPPOSITE_PLACEMENT | StandardBlocks.CFG_AI_PASSABLE,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.5f, 8f).sound(SoundType.METAL).lightLevel((state)->15).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.5f, 8f).sound(SoundType.METAL).lightLevel((state) -> 15).noOcclusion(),
new AABB[]{
Auxiliaries.getPixeledAABB(6.5, 6.5, 1, 9.5, 9.5, 4),
Auxiliaries.getPixeledAABB(6.0, 6.0, 0, 10.0, 10.0, 1.0)
@ -397,12 +366,12 @@ public class ModContent
Registries.addBlock("steel_table", () -> new StandardBlocks.WaterLoggable(
StandardBlocks.CFG_CUTOUT,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.5f, 8f).sound(SoundType.METAL).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.5f, 8f).sound(SoundType.METAL).noOcclusion(),
Auxiliaries.getPixeledAABB(0, 0, 0, 16, 16, 16)
));
Registries.addBlock("steel_floor_grating", () -> new EdFloorGratingBlock(
StandardBlocks.CFG_CUTOUT,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.5f, 8f).sound(SoundType.METAL).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.5f, 8f).sound(SoundType.METAL).noOcclusion(),
Auxiliaries.getPixeledAABB(0, 14, 0, 16, 15.5, 16)
));
@ -410,7 +379,7 @@ public class ModContent
Registries.addBlock("steel_framed_window", () -> new EdWindowBlock(
StandardBlocks.CFG_LOOK_PLACEMENT,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.5f, 8f).sound(SoundType.METAL).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.5f, 8f).sound(SoundType.METAL).noOcclusion(),
Auxiliaries.getPixeledAABB(0, 0, 7.5, 16, 16, 8.5)
));
@ -418,49 +387,49 @@ public class ModContent
Registries.addBlock("treated_wood_pole", () -> new EdStraightPoleBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_FLIP_PLACEMENT_IF_SAME,
BlockBehaviour.Properties.of(Material.WOOD, MaterialColor.WOOD).strength(0.5f, 5f).sound(SoundType.WOOD).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.5f, 5f).sound(SoundType.WOOD).noOcclusion(),
Auxiliaries.getPixeledAABB(5.8, 5.8, 0, 10.2, 10.2, 16),
null
));
Registries.addBlock("treated_wood_pole_head", () -> new EdStraightPoleBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_FLIP_PLACEMENT_IF_SAME,
BlockBehaviour.Properties.of(Material.WOOD, MaterialColor.WOOD).strength(0.5f, 5f).sound(SoundType.WOOD).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.5f, 5f).sound(SoundType.WOOD).noOcclusion(),
Auxiliaries.getPixeledAABB(5.8, 5.8, 0, 10.2, 10.2, 16),
(EdStraightPoleBlock) Registries.getBlock("treated_wood_pole") // TREATED_WOOD_POLE
));
Registries.addBlock("treated_wood_pole_support", () -> new EdStraightPoleBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_FLIP_PLACEMENT_IF_SAME,
BlockBehaviour.Properties.of(Material.WOOD, MaterialColor.WOOD).strength(0.5f, 5f).sound(SoundType.WOOD).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.5f, 5f).sound(SoundType.WOOD).noOcclusion(),
Auxiliaries.getPixeledAABB(5.8, 5.8, 0, 10.2, 10.2, 16),
(EdStraightPoleBlock) Registries.getBlock("treated_wood_pole") // TREATED_WOOD_POLE
));
Registries.addBlock("thin_steel_pole", () -> new EdStraightPoleBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.5f, 11f).sound(SoundType.METAL).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.5f, 11f).sound(SoundType.METAL).noOcclusion(),
Auxiliaries.getPixeledAABB(6, 6, 0, 10, 10, 16),
null
));
Registries.addBlock("thin_steel_pole_head", () -> new EdStraightPoleBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_FLIP_PLACEMENT_IF_SAME,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.5f, 11f).sound(SoundType.METAL).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.5f, 11f).sound(SoundType.METAL).noOcclusion(),
Auxiliaries.getPixeledAABB(6, 6, 0, 10, 10, 16),
(EdStraightPoleBlock) Registries.getBlock("thin_steel_pole") // THIN_STEEL_POLE
));
Registries.addBlock("thick_steel_pole", () -> new EdStraightPoleBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.5f, 11f).sound(SoundType.METAL).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.5f, 11f).sound(SoundType.METAL).noOcclusion(),
Auxiliaries.getPixeledAABB(5, 5, 0, 11, 11, 16),
null
));
Registries.addBlock("thick_steel_pole_head", () -> new EdStraightPoleBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_FLIP_PLACEMENT_IF_SAME,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.5f, 11f).sound(SoundType.METAL).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.5f, 11f).sound(SoundType.METAL).noOcclusion(),
Auxiliaries.getPixeledAABB(5, 5, 0, 11, 11, 16),
(EdStraightPoleBlock) Registries.getBlock("thin_steel_pole")
));
Registries.addBlock("steel_double_t_support", () -> new EdHorizontalSupportBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_LOOK_PLACEMENT,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.5f, 11f).sound(SoundType.METAL).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.5f, 11f).sound(SoundType.METAL).noOcclusion(),
Auxiliaries.getPixeledAABB(5, 11, 0, 11, 16, 16), // main beam
Auxiliaries.getPixeledAABB(10, 11, 5, 16, 16, 11), // east beam (also for west 180deg)
Auxiliaries.getPixeledAABB(6, 0, 6, 10, 16, 10), // down thin
@ -471,30 +440,30 @@ public class ModContent
Registries.addBlock("steel_mesh_fence", () -> new EdFenceBlock(
StandardBlocks.CFG_CUTOUT,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.3f, 10f).sound(SoundType.METAL).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.3f, 10f).sound(SoundType.METAL).noOcclusion(),
1.5, 16, 0.25, 0, 16, 16
));
Registries.addBlock("steel_mesh_fence_gate", () -> new EdDoubleGateBlock(
StandardBlocks.CFG_CUTOUT,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.3f, 10f).sound(SoundType.METAL).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.3f, 10f).sound(SoundType.METAL).noOcclusion(),
Auxiliaries.getPixeledAABB(0, 0, 6.5, 16, 16, 9.5)
));
Registries.addBlock("steel_railing", () -> new EdgeAlignedRailingBlock(
StandardBlocks.CFG_CUTOUT,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.3f, 10f).sound(SoundType.METAL).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.3f, 10f).sound(SoundType.METAL).noOcclusion(),
Auxiliaries.getPixeledAABB(0, 0, 0, 0, 0, 0),
Auxiliaries.getPixeledAABB(0, 0, 0, 16, 15.9, 1)
));
Registries.addBlock("steel_catwalk", () -> new EdCatwalkBlock(
StandardBlocks.CFG_CUTOUT,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.3f, 10f).sound(SoundType.METAL).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.3f, 10f).sound(SoundType.METAL).noOcclusion(),
Auxiliaries.getPixeledAABB(0, 0, 0, 16, 2, 16),
Auxiliaries.getPixeledAABB(0, 0, 0, 16, 15.9, 1),
Registries.getBlock("steel_railing")
));
Registries.addBlock("steel_catwalk_ta", () -> new EdCatwalkTopAlignedBlock(
StandardBlocks.CFG_CUTOUT,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.3f, 10f).sound(SoundType.METAL).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.3f, 10f).sound(SoundType.METAL).noOcclusion(),
new VoxelShape[]{
Shapes.create(Auxiliaries.getPixeledAABB(0, 14, 0, 16, 16, 16)), // only base
Auxiliaries.getUnionShape( // base with thick pole
@ -521,7 +490,7 @@ public class ModContent
));
Registries.addBlock("steel_catwalk_stairs", () -> new EdCatwalkStairsBlock(
StandardBlocks.CFG_CUTOUT,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.3f, 10f).sound(SoundType.METAL).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.3f, 10f).sound(SoundType.METAL).noOcclusion(),
new AABB[]{ // base
Auxiliaries.getPixeledAABB(1, 2, 8, 15, 4, 16),
Auxiliaries.getPixeledAABB(1, 10, 0, 15, 12, 8),
@ -550,67 +519,67 @@ public class ModContent
Registries.addBlock("sign_decor", () -> new StandardBlocks.DirectedWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_AI_PASSABLE,
BlockBehaviour.Properties.of(Material.WOOD, MaterialColor.WOOD).strength(0.3f, 1000f).sound(SoundType.WOOD).lightLevel((state)->1).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.3f, 1000f).sound(SoundType.WOOD).lightLevel((state) -> 1).noOcclusion(),
Auxiliaries.getPixeledAABB(0, 0, 15.6, 16, 16, 16.0)
));
Registries.addBlock("sign_hotwire", () -> new StandardBlocks.DirectedWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_AI_PASSABLE,
BlockBehaviour.Properties.of(Material.WOOD, MaterialColor.WOOD).strength(0.2f, 1f).sound(SoundType.WOOD).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.2f, 1f).sound(SoundType.WOOD).noOcclusion(),
Auxiliaries.getPixeledAABB(2, 2, 15.6, 14, 14, 16)
));
Registries.addBlock("sign_danger", () -> new StandardBlocks.DirectedWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_AI_PASSABLE,
BlockBehaviour.Properties.of(Material.WOOD, MaterialColor.WOOD).strength(0.2f, 1f).sound(SoundType.WOOD).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.2f, 1f).sound(SoundType.WOOD).noOcclusion(),
Auxiliaries.getPixeledAABB(2, 2, 15.6, 14, 14, 16)
));
Registries.addBlock("sign_radioactive", () -> new StandardBlocks.DirectedWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_AI_PASSABLE,
BlockBehaviour.Properties.of(Material.WOOD, MaterialColor.WOOD).strength(0.2f, 1f).sound(SoundType.WOOD).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.2f, 1f).sound(SoundType.WOOD).noOcclusion(),
Auxiliaries.getPixeledAABB(2, 2, 15.6, 14, 14, 16)
));
Registries.addBlock("sign_laser", () -> new StandardBlocks.DirectedWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_AI_PASSABLE,
BlockBehaviour.Properties.of(Material.WOOD, MaterialColor.WOOD).strength(0.2f, 1f).sound(SoundType.WOOD).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.2f, 1f).sound(SoundType.WOOD).noOcclusion(),
Auxiliaries.getPixeledAABB(2, 2, 15.6, 14, 14, 16)
));
Registries.addBlock("sign_caution", () -> new StandardBlocks.DirectedWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_AI_PASSABLE,
BlockBehaviour.Properties.of(Material.WOOD, MaterialColor.WOOD).strength(0.2f, 1f).sound(SoundType.WOOD).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.2f, 1f).sound(SoundType.WOOD).noOcclusion(),
Auxiliaries.getPixeledAABB(2, 2, 15.6, 14, 14, 16)
));
Registries.addBlock("sign_magichazard", () -> new StandardBlocks.DirectedWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_AI_PASSABLE,
BlockBehaviour.Properties.of(Material.WOOD, MaterialColor.WOOD).strength(0.2f, 1f).sound(SoundType.WOOD).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.2f, 1f).sound(SoundType.WOOD).noOcclusion(),
Auxiliaries.getPixeledAABB(2, 2, 15.6, 14, 14, 16)
));
Registries.addBlock("sign_firehazard", () -> new StandardBlocks.DirectedWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_AI_PASSABLE,
BlockBehaviour.Properties.of(Material.WOOD, MaterialColor.WOOD).strength(0.2f, 1f).sound(SoundType.WOOD).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.2f, 1f).sound(SoundType.WOOD).noOcclusion(),
Auxiliaries.getPixeledAABB(2, 2, 15.6, 14, 14, 16)
));
Registries.addBlock("sign_hotsurface", () -> new StandardBlocks.DirectedWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_AI_PASSABLE,
BlockBehaviour.Properties.of(Material.WOOD, MaterialColor.WOOD).strength(0.2f, 1f).sound(SoundType.WOOD).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.2f, 1f).sound(SoundType.WOOD).noOcclusion(),
Auxiliaries.getPixeledAABB(2, 2, 15.6, 14, 14, 16)
));
Registries.addBlock("sign_magneticfield", () -> new StandardBlocks.DirectedWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_AI_PASSABLE,
BlockBehaviour.Properties.of(Material.WOOD, MaterialColor.WOOD).strength(0.2f, 1f).sound(SoundType.WOOD).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.2f, 1f).sound(SoundType.WOOD).noOcclusion(),
Auxiliaries.getPixeledAABB(2, 2, 15.6, 14, 14, 16)
));
Registries.addBlock("sign_frost", () -> new StandardBlocks.DirectedWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_AI_PASSABLE,
BlockBehaviour.Properties.of(Material.WOOD, MaterialColor.WOOD).strength(0.2f, 1f).sound(SoundType.WOOD).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.2f, 1f).sound(SoundType.WOOD).noOcclusion(),
Auxiliaries.getPixeledAABB(2, 2, 15.6, 14, 14, 16)
));
Registries.addBlock("sign_exit", () -> new StandardBlocks.DirectedWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_AI_PASSABLE,
BlockBehaviour.Properties.of(Material.WOOD, MaterialColor.WOOD).strength(0.2f, 1f).sound(SoundType.WOOD).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.2f, 1f).sound(SoundType.WOOD).noOcclusion(),
Auxiliaries.getPixeledAABB(3, 7, 15.6, 13, 13, 16)
));
Registries.addBlock("sign_defense", () -> new StandardBlocks.DirectedWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_AI_PASSABLE,
BlockBehaviour.Properties.of(Material.WOOD, MaterialColor.WOOD).strength(0.2f, 1f).sound(SoundType.WOOD).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.2f, 1f).sound(SoundType.WOOD).noOcclusion(),
Auxiliaries.getPixeledAABB(2, 2, 15.6, 14, 14, 16)
));
@ -619,19 +588,19 @@ public class ModContent
Registries.addBlock("small_lab_furnace",
() -> new EdFurnace.FurnaceBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_LOOK_PLACEMENT | StandardBlocks.CFG_OPPOSITE_PLACEMENT,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.3f, 12f).sound(SoundType.METAL).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.3f, 12f).sound(SoundType.METAL).noOcclusion(),
new AABB[]{
Auxiliaries.getPixeledAABB(1, 0, 1, 15, 1, 15),
Auxiliaries.getPixeledAABB(0, 1, 1, 16, 16, 16),
}
),
EdFurnace.FurnaceTileEntity::new,
EdFurnace.FurnaceContainer::new
EdFurnace.FurnaceTileEntity::new
);
Registries.addBlock("small_electrical_furnace",
() -> new EdElectricalFurnace.ElectricalFurnaceBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_LOOK_PLACEMENT | StandardBlocks.CFG_OPPOSITE_PLACEMENT,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.3f, 12f).sound(SoundType.METAL).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.3f, 12f).sound(SoundType.METAL).noOcclusion(),
new AABB[]{
Auxiliaries.getPixeledAABB(0, 0, 0, 16, 11, 16),
Auxiliaries.getPixeledAABB(1, 11, 0, 15, 12, 16),
@ -640,35 +609,32 @@ public class ModContent
Auxiliaries.getPixeledAABB(4, 14, 0, 12, 16, 16),
}
),
EdElectricalFurnace.ElectricalFurnaceTileEntity::new,
EdElectricalFurnace.ElectricalFurnaceContainer::new
EdElectricalFurnace.ElectricalFurnaceTileEntity::new
);
Registries.addBlock("factory_dropper",
() -> new EdDropper.DropperBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_LOOK_PLACEMENT | StandardBlocks.CFG_OPPOSITE_PLACEMENT,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.3f, 12f).sound(SoundType.METAL).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.3f, 12f).sound(SoundType.METAL).noOcclusion(),
Auxiliaries.getPixeledAABB(0, 0, 1, 16, 16, 16)
),
EdDropper.DropperTileEntity::new,
EdDropper.DropperUiContainer::new
EdDropper.DropperTileEntity::new
);
Registries.addBlock("factory_placer",
() -> new EdPlacer.PlacerBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_LOOK_PLACEMENT | StandardBlocks.CFG_FLIP_PLACEMENT_SHIFTCLICK | StandardBlocks.CFG_OPPOSITE_PLACEMENT,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.3f, 12f).sound(SoundType.METAL).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.3f, 12f).sound(SoundType.METAL).noOcclusion(),
new AABB[]{
Auxiliaries.getPixeledAABB(0, 0, 2, 16, 16, 16),
Auxiliaries.getPixeledAABB(0, 0, 0, 1, 16, 2),
Auxiliaries.getPixeledAABB(15, 0, 0, 16, 16, 2)
}
),
EdPlacer.PlacerTileEntity::new,
EdPlacer.PlacerContainer::new
EdPlacer.PlacerTileEntity::new
);
Registries.addBlock("small_block_breaker",
() -> new EdBreaker.BreakerBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_LOOK_PLACEMENT | StandardBlocks.CFG_OPPOSITE_PLACEMENT | StandardBlocks.CFG_FLIP_PLACEMENT_SHIFTCLICK,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.3f, 12f).sound(SoundType.METAL).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.3f, 12f).sound(SoundType.METAL).noOcclusion(),
new AABB[]{
Auxiliaries.getPixeledAABB(1, 0, 0, 15, 4, 7),
Auxiliaries.getPixeledAABB(1, 0, 7, 15, 12, 16),
@ -683,7 +649,7 @@ public class ModContent
Registries.addBlock("factory_hopper",
() -> new EdHopper.HopperBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_OPPOSITE_PLACEMENT,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.3f, 12f).sound(SoundType.METAL).noOcclusion(),()->{
BlockBehaviour.Properties.of().strength(0.3f, 12f).sound(SoundType.METAL).noOcclusion(), () -> {
final AABB[] down_aabbs = new AABB[]{
Auxiliaries.getPixeledAABB(5, 0, 5, 11, 1, 11),
Auxiliaries.getPixeledAABB(4, 1, 4, 12, 7, 12),
@ -726,22 +692,20 @@ public class ModContent
));
}
),
EdHopper.HopperTileEntity::new,
EdHopper.HopperContainer::new
EdHopper.HopperTileEntity::new
);
Registries.addBlock("small_waste_incinerator",
() -> new EdWasteIncinerator.WasteIncineratorBlock(
StandardBlocks.CFG_DEFAULT,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.3f, 12f).sound(SoundType.METAL),
BlockBehaviour.Properties.of().strength(0.3f, 12f).sound(SoundType.METAL),
Auxiliaries.getPixeledAABB(0, 0, 0, 16, 16, 16)
),
EdWasteIncinerator.WasteIncineratorTileEntity::new,
EdWasteIncinerator.WasteIncineratorContainer::new
EdWasteIncinerator.WasteIncineratorTileEntity::new
);
Registries.addBlock("small_mineral_smelter",
() -> new EdMineralSmelter.MineralSmelterBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_LOOK_PLACEMENT,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.3f, 12f).sound(SoundType.METAL).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.3f, 12f).sound(SoundType.METAL).noOcclusion(),
Auxiliaries.getPixeledAABB(1.1, 0, 1.1, 14.9, 16, 14.9)
),
EdMineralSmelter.MineralSmelterTileEntity::new
@ -749,7 +713,7 @@ public class ModContent
Registries.addBlock("small_freezer",
() -> new EdFreezer.FreezerBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_LOOK_PLACEMENT,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.3f, 12f).sound(SoundType.METAL).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.3f, 12f).sound(SoundType.METAL).noOcclusion(),
Auxiliaries.getPixeledAABB(1.1, 0, 1.1, 14.9, 16, 14.9)
),
EdFreezer.FreezerTileEntity::new
@ -757,7 +721,7 @@ public class ModContent
Registries.addBlock("small_solar_panel",
() -> new EdSolarPanel.SolarPanelBlock(
StandardBlocks.CFG_CUTOUT,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.3f, 10f).sound(SoundType.METAL).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.3f, 10f).sound(SoundType.METAL).noOcclusion(),
new AABB[]{
Auxiliaries.getPixeledAABB(0, 0, 0, 16, 2, 16),
Auxiliaries.getPixeledAABB(6, 1.5, 3, 10, 10.5, 13),
@ -768,7 +732,7 @@ public class ModContent
Registries.addBlock("small_milking_machine",
() -> new EdMilker.MilkerBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_LOOK_PLACEMENT,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.3f, 10f).sound(SoundType.METAL).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.3f, 10f).sound(SoundType.METAL).noOcclusion(),
new AABB[]{
Auxiliaries.getPixeledAABB(1, 1, 0, 15, 14, 10),
Auxiliaries.getPixeledAABB(0, 14, 0, 16, 16, 13),
@ -782,7 +746,7 @@ public class ModContent
Registries.addBlock("small_tree_cutter",
() -> new EdTreeCutter.TreeCutterBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_LOOK_PLACEMENT | StandardBlocks.CFG_FLIP_PLACEMENT_SHIFTCLICK,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.3f, 10f).sound(SoundType.METAL).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.3f, 10f).sound(SoundType.METAL).noOcclusion(),
new AABB[]{
Auxiliaries.getPixeledAABB(0, 0, 0, 16, 3, 16),
Auxiliaries.getPixeledAABB(0, 3, 0, 3, 8, 16),
@ -797,7 +761,7 @@ public class ModContent
Registries.addBlock("straight_pipe_valve", () -> new EdPipeValve.PipeValveBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_OPPOSITE_PLACEMENT | StandardBlocks.CFG_FLIP_PLACEMENT_SHIFTCLICK,
EdPipeValve.CFG_CHECK_VALVE,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.3f, 8f).sound(SoundType.METAL).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.3f, 8f).sound(SoundType.METAL).noOcclusion(),
new AABB[]{
Auxiliaries.getPixeledAABB(2, 2, 0, 14, 14, 2),
Auxiliaries.getPixeledAABB(2, 2, 14, 14, 14, 16),
@ -808,7 +772,7 @@ public class ModContent
Registries.addBlock("straight_pipe_valve_redstone", () -> new EdPipeValve.PipeValveBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_OPPOSITE_PLACEMENT,
EdPipeValve.CFG_REDSTONE_CONTROLLED_VALVE,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.3f, 8f).sound(SoundType.METAL).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.3f, 8f).sound(SoundType.METAL).noOcclusion(),
new AABB[]{
Auxiliaries.getPixeledAABB(2, 2, 0, 14, 14, 2),
Auxiliaries.getPixeledAABB(2, 2, 14, 14, 14, 16),
@ -820,7 +784,7 @@ public class ModContent
() -> new EdPipeValve.PipeValveBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_OPPOSITE_PLACEMENT,
EdPipeValve.CFG_REDSTONE_CONTROLLED_VALVE | EdPipeValve.CFG_ANALOG_VALVE,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.3f, 8f).sound(SoundType.METAL).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.3f, 8f).sound(SoundType.METAL).noOcclusion(),
new AABB[]{
Auxiliaries.getPixeledAABB(2, 2, 0, 14, 14, 2),
Auxiliaries.getPixeledAABB(2, 2, 14, 14, 14, 16),
@ -836,7 +800,7 @@ public class ModContent
Registries.addBlock("fluid_barrel",
() -> new EdFluidBarrel.FluidBarrelBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_LOOK_PLACEMENT | StandardBlocks.CFG_OPPOSITE_PLACEMENT,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.3f, 10f).sound(SoundType.METAL).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.3f, 10f).sound(SoundType.METAL).noOcclusion(),
new AABB[]{
Auxiliaries.getPixeledAABB(2, 0, 0, 14, 1, 16),
Auxiliaries.getPixeledAABB(1, 1, 0, 15, 2, 16),
@ -851,7 +815,7 @@ public class ModContent
Registries.addBlock("small_fluid_funnel",
() -> new EdFluidFunnel.FluidFunnelBlock(
StandardBlocks.CFG_CUTOUT,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0.3f, 10f).sound(SoundType.METAL).noOcclusion(),
BlockBehaviour.Properties.of().strength(0.3f, 10f).sound(SoundType.METAL).noOcclusion(),
new AABB[]{
Auxiliaries.getPixeledAABB(0, 0, 0, 16, 14, 16),
Auxiliaries.getPixeledAABB(1, 14, 1, 15, 15, 15),
@ -866,7 +830,7 @@ public class ModContent
Registries.addBlock("test_block",
() -> new EdTestBlock.TestBlock(
StandardBlocks.CFG_LOOK_PLACEMENT,
BlockBehaviour.Properties.of(Material.METAL, MaterialColor.METAL).strength(0f, 32000f).sound(SoundType.METAL),
BlockBehaviour.Properties.of().strength(0f, 32000f).sound(SoundType.METAL),
Auxiliaries.getPixeledAABB(0, 0, 0, 16, 16, 16)
),
EdTestBlock.TestTileEntity::new
@ -874,13 +838,11 @@ public class ModContent
}
public static void initItems()
{
Registries.addItem("metal_bar", ()->new EdItem((new Item.Properties()).tab(Registries.getCreativeModeTab())));
public static void initItems() {
Registries.addItem("metal_bar", () -> new EdItem((new Item.Properties())));
}
public static void initEntities()
{
public static void initEntities() {
Registries.addEntityType("et_chair", () ->
EntityType.Builder.of(EdChair.EntityChair::new, MobCategory.MISC)
.fireImmune().sized(1e-3f, 1e-3f).noSave()
@ -890,50 +852,55 @@ public class ModContent
);
}
public static Block getBlock(String name) {
return Registries.getBlock(name);
}
//--------------------------------------------------------------------------------------------------------------------
// Registry wrappers
//--------------------------------------------------------------------------------------------------------------------
public static Block getBlock(String name)
{ return Registries.getBlock(name); }
public static Item getItem(String name) {
return Registries.getItem(name);
}
public static Item getItem(String name)
{ return Registries.getItem(name); }
public static TagKey<Block> getBlockTagKey(String name) {
return Registries.getBlockTagKey(name);
}
public static TagKey<Block> getBlockTagKey(String name)
{ return Registries.getBlockTagKey(name); }
public static TagKey<Item> getItemTagKey(String name) {
return Registries.getItemTagKey(name);
}
public static TagKey<Item> getItemTagKey(String name)
{ return Registries.getItemTagKey(name); }
public static BlockEntityType<?> getBlockEntityTypeOfBlock(String block_name) {
return Registries.getBlockEntityTypeOfBlock(block_name);
}
public static BlockEntityType<?> getBlockEntityTypeOfBlock(String block_name)
{ return Registries.getBlockEntityTypeOfBlock(block_name); }
public static BlockEntityType<?> getBlockEntityTypeOfBlock(Block block) {
return Registries.getBlockEntityTypeOfBlock(block);
}
public static BlockEntityType<?> getBlockEntityTypeOfBlock(Block block)
{ return Registries.getBlockEntityTypeOfBlock(block); }
public static EntityType<?> getEntityType(String name) {
return Registries.getEntityType(name);
}
public static EntityType<?> getEntityType(String name)
{ return Registries.getEntityType(name); }
public static MenuType<?> getMenuType(String block_name)
{ return Registries.getMenuTypeOfBlock(block_name); }
public static MenuType<?> getMenuType(String block_name) {
return Registries.getMenuTypeOfBlock(block_name);
}
@Nonnull
public static List<Block> getRegisteredBlocks()
{ return Registries.getRegisteredBlocks(); }
public static List<Block> getRegisteredBlocks() {
return Registries.getRegisteredBlocks();
}
@Nonnull
public static List<Item> getRegisteredItems()
{ return Registries.getRegisteredItems(); }
//--------------------------------------------------------------------------------------------------------------------
// Initialisation events
//--------------------------------------------------------------------------------------------------------------------
public static List<Item> getRegisteredItems() {
return Registries.getRegisteredItems();
}
@OnlyIn(Dist.CLIENT)
@SuppressWarnings("unchecked")
public static void registerMenuGuis(final FMLClientSetupEvent event)
{
public static void registerMenuGuis(final FMLClientSetupEvent event) {
MenuScreens.register((MenuType<EdDropper.DropperUiContainer>) Registries.getMenuTypeOfBlock("factory_dropper"), EdDropper.DropperGui::new);
MenuScreens.register((MenuType<EdPlacer.PlacerContainer>) Registries.getMenuTypeOfBlock("factory_placer"), EdPlacer.PlacerGui::new);
MenuScreens.register((MenuType<EdHopper.HopperContainer>) Registries.getMenuTypeOfBlock("factory_hopper"), EdHopper.HopperGui::new);
@ -942,15 +909,17 @@ public class ModContent
MenuScreens.register((MenuType<EdWasteIncinerator.WasteIncineratorContainer>) Registries.getMenuTypeOfBlock("small_waste_incinerator"), EdWasteIncinerator.WasteIncineratorGui::new);
}
//--------------------------------------------------------------------------------------------------------------------
// Initialisation events
//--------------------------------------------------------------------------------------------------------------------
@OnlyIn(Dist.CLIENT)
@SuppressWarnings("unchecked")
public static void registerBlockEntityRenderers(final FMLClientSetupEvent event)
{
public static void registerBlockEntityRenderers(final FMLClientSetupEvent event) {
}
@OnlyIn(Dist.CLIENT)
public static void processContentClientSide(final FMLClientSetupEvent event)
{
public static void processContentClientSide(final FMLClientSetupEvent event) {
// Block renderer selection
// Disabled in Forge, model based {"render_type": "cutout"/"translucent"}
// for(Block block: Registries.getRegisteredBlocks()) {
@ -968,4 +937,12 @@ public class ModContent
EntityRenderers.register(Registries.getEntityType("et_chair"), ModRenderers.InvisibleEntityRenderer::new);
}
private static class detail {
public static String MODID = "";
public static Boolean disallowSpawn(BlockState state, BlockGetter reader, BlockPos pos, EntityType<?> entity) {
return false;
}
}
}

View file

@ -1,7 +1,7 @@
package dev.zontreck.engineerdecor;
import dev.zontreck.engineerdecor.blocks.EdLadderBlock;
import dev.zontreck.engineerdecor.libmc.*;
import dev.zontreck.libzontreck.edlibmc.*;
import net.minecraft.world.entity.player.Player;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
@ -16,25 +16,19 @@ import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import org.slf4j.Logger;
import dev.zontreck.engineerdecor.libmc.Auxiliaries;
import dev.zontreck.engineerdecor.libmc.OptionalRecipeCondition;
import dev.zontreck.engineerdecor.libmc.Overlay;
import dev.zontreck.engineerdecor.libmc.Registries;
@Mod("engineersdecor")
public class ModEngineersDecor
{
public class ModEngineersDecor {
public static final String MODID = "engineersdecor";
public static final String MODNAME = "Engineer's Decor";
public static final int VERSION_DATAFIXER = 0;
private static final Logger LOGGER = com.mojang.logging.LogUtils.getLogger();
public ModEngineersDecor()
{
public ModEngineersDecor() {
Auxiliaries.init(MODID, LOGGER, ModConfig::getServerConfig);
Auxiliaries.logGitVersion(MODNAME);
Registries.init(MODID, "sign_decor", (reg)->reg.register(FMLJavaModLoadingContext.get().getModEventBus()));
Registries.init(MODID, "sign_decor", FMLJavaModLoadingContext.get().getModEventBus());
ModContent.init(MODID);
OptionalRecipeCondition.init(MODID, LOGGER);
ModLoadingContext.get().registerConfig(net.minecraftforge.fml.config.ModConfig.Type.SERVER, ModConfig.SERVER_CONFIG_SPEC);
@ -44,14 +38,12 @@ public class ModEngineersDecor
MinecraftForge.EVENT_BUS.register(this);
}
private void onSetup(final FMLCommonSetupEvent event)
{
private void onSetup(final FMLCommonSetupEvent event) {
CraftingHelper.register(OptionalRecipeCondition.Serializer.INSTANCE);
Networking.init(MODID);
}
private void onClientSetup(final FMLClientSetupEvent event)
{
private void onClientSetup(final FMLClientSetupEvent event) {
Overlay.TextOverlayGui.on_config(0.75, 0x00ffaa00, 0x55333333, 0x55333333, 0x55444444);
Networking.OverlayTextMessage.setHandler(Overlay.TextOverlayGui::show);
ModContent.registerMenuGuis(event);
@ -59,16 +51,21 @@ public class ModEngineersDecor
ModContent.processContentClientSide(event);
}
@Mod.EventBusSubscriber(bus=Mod.EventBusSubscriber.Bus.MOD)
public static class ForgeEvents
{
@SubscribeEvent
public static void onConfigLoad(final ModConfigEvent.Loading event)
{ ModConfig.apply(); }
public void onPlayerEvent(final LivingEvent.LivingTickEvent event) {
if (!(event.getEntity() instanceof final Player player)) return;
if (player.onClimbable()) EdLadderBlock.onPlayerUpdateEvent(player);
}
@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD)
public static class ForgeEvents {
@SubscribeEvent
public static void onConfigLoad(final ModConfigEvent.Loading event) {
ModConfig.apply();
}
@SubscribeEvent
public static void onConfigReload(final ModConfigEvent.Reloading event)
{
public static void onConfigReload(final ModConfigEvent.Reloading event) {
try {
Auxiliaries.logger().info("Config file changed {}", event.getConfig().getFileName());
ModConfig.apply();
@ -78,25 +75,17 @@ public class ModEngineersDecor
}
}
@SubscribeEvent
public void onPlayerEvent(final LivingEvent.LivingTickEvent event)
{
if(!(event.getEntity() instanceof final Player player)) return;
if(player.onClimbable()) EdLadderBlock.onPlayerUpdateEvent(player);
}
@OnlyIn(Dist.CLIENT)
@Mod.EventBusSubscriber(Dist.CLIENT)
public static class ForgeClientEvents
{
public static class ForgeClientEvents {
@SubscribeEvent
public static void onRenderGui(net.minecraftforge.client.event.RenderGuiOverlayEvent.Post event)
{ Overlay.TextOverlayGui.INSTANCE.onRenderGui(event.getPoseStack()); }
public static void onRenderGui(net.minecraftforge.client.event.RenderGuiOverlayEvent.Post event) {
Overlay.TextOverlayGui.INSTANCE.onRenderGui(event.getGuiGraphics());
}
@SubscribeEvent
@OnlyIn(Dist.CLIENT)
public static void onRenderWorldOverlay(net.minecraftforge.client.event.RenderLevelStageEvent event)
{
public static void onRenderWorldOverlay(net.minecraftforge.client.event.RenderLevelStageEvent event) {
if (event.getStage() == net.minecraftforge.client.event.RenderLevelStageEvent.Stage.AFTER_WEATHER) {
Overlay.TextOverlayGui.INSTANCE.onRenderWorldOverlay(event.getPoseStack(), event.getPartialTick());
}

View file

@ -8,6 +8,9 @@
*/
package dev.zontreck.engineerdecor.blocks;
import dev.zontreck.engineerdecor.ModConfig;
import dev.zontreck.engineerdecor.ModContent;
import dev.zontreck.libzontreck.edlibmc.*;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.particles.ParticleTypes;
@ -28,6 +31,7 @@ import net.minecraft.world.level.GameRules;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.LiquidBlock;
import net.minecraft.world.level.block.SoundType;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockBehaviour;
@ -41,14 +45,6 @@ import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.capabilities.ForgeCapabilities;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.energy.IEnergyStorage;
import dev.zontreck.engineerdecor.ModConfig;
import dev.zontreck.engineerdecor.ModContent;
import dev.zontreck.engineerdecor.libmc.StandardBlocks;
import dev.zontreck.engineerdecor.libmc.StandardEntityBlocks;
import dev.zontreck.engineerdecor.libmc.Auxiliaries;
import dev.zontreck.engineerdecor.libmc.Inventories;
import dev.zontreck.engineerdecor.libmc.Overlay;
import dev.zontreck.engineerdecor.libmc.RfEnergy;
import javax.annotation.Nullable;
import java.util.HashSet;
@ -56,8 +52,7 @@ import java.util.List;
import java.util.Random;
public class EdBreaker
{
public class EdBreaker {
public static final int BOOST_FACTOR = 8;
public static final int DEFAULT_BOOST_ENERGY = 64;
public static final int DEFAULT_BREAKING_RELUCTANCE = 17;
@ -70,8 +65,7 @@ public class EdBreaker
private static int min_breaking_time = DEFAULT_MIN_BREAKING_TIME;
private static boolean requires_power = false;
public static void on_config(int boost_energy_per_tick, int breaking_time_per_hardness, int min_breaking_time_ticks, boolean power_required)
{
public static void on_config(int boost_energy_per_tick, int breaking_time_per_hardness, int min_breaking_time_ticks, boolean power_required) {
final int interval = BreakerTileEntity.TICK_INTERVAL;
boost_energy_consumption = interval * Mth.clamp(boost_energy_per_tick, 4, 4096);
energy_max = Math.max(boost_energy_consumption * 10, 100000);
@ -85,30 +79,33 @@ public class EdBreaker
// Block
//--------------------------------------------------------------------------------------------------------------------
public static class BreakerBlock extends StandardBlocks.HorizontalWaterLoggable implements StandardEntityBlocks.IStandardEntityBlock<BreakerTileEntity>
{
public static class BreakerBlock extends StandardBlocks.HorizontalWaterLoggable implements StandardEntityBlocks.IStandardEntityBlock<BreakerTileEntity> {
public static final BooleanProperty ACTIVE = BooleanProperty.create("active");
public BreakerBlock(long config, BlockBehaviour.Properties builder, final AABB[] unrotatedAABBs)
{ super(config, builder, unrotatedAABBs); }
public BreakerBlock(long config, BlockBehaviour.Properties builder, final AABB[] unrotatedAABBs) {
super(config, builder, unrotatedAABBs);
}
@Override
public boolean isBlockEntityTicking(Level world, BlockState state)
{ return true; }
public boolean isBlockEntityTicking(Level world, BlockState state) {
return true;
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder)
{ super.createBlockStateDefinition(builder); builder.add(ACTIVE); }
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
super.createBlockStateDefinition(builder);
builder.add(ACTIVE);
}
@Override
@Nullable
public BlockState getStateForPlacement(BlockPlaceContext context)
{ return super.getStateForPlacement(context).setValue(ACTIVE, false); }
public BlockState getStateForPlacement(BlockPlaceContext context) {
return super.getStateForPlacement(context).setValue(ACTIVE, false);
}
@OnlyIn(Dist.CLIENT)
@SuppressWarnings("deprecation")
public void animateTick(BlockState state, Level world, BlockPos pos, Random rnd)
{
public void animateTick(BlockState state, Level world, BlockPos pos, Random rnd) {
if ((state.getBlock() != this) || (!state.getValue(ACTIVE))) return;
// Sound
{
@ -140,8 +137,7 @@ public class EdBreaker
@Override
@SuppressWarnings("deprecation")
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block block, BlockPos fromPos, boolean unused)
{
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block block, BlockPos fromPos, boolean unused) {
if (!(world instanceof Level) || (world.isClientSide)) return;
BlockEntity te = world.getBlockEntity(pos);
if (!(te instanceof BreakerTileEntity)) return;
@ -150,23 +146,25 @@ public class EdBreaker
@Override
@SuppressWarnings("deprecation")
public boolean isSignalSource(BlockState state)
{ return true; }
public boolean isSignalSource(BlockState state) {
return true;
}
@Override
@SuppressWarnings("deprecation")
public int getSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side)
{ return 0; }
public int getSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side) {
return 0;
}
@Override
@SuppressWarnings("deprecation")
public int getDirectSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side)
{ return 0; }
public int getDirectSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side) {
return 0;
}
@Override
@SuppressWarnings("deprecation")
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit)
{
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
if (world.isClientSide()) return InteractionResult.SUCCESS;
BlockEntity te = world.getBlockEntity(pos);
if (te instanceof BreakerTileEntity) ((BreakerTileEntity) te).state_message(player);
@ -178,67 +176,11 @@ public class EdBreaker
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
public static class BreakerTileEntity extends StandardEntityBlocks.StandardBlockEntity
{
public static class BreakerTileEntity extends StandardEntityBlocks.StandardBlockEntity {
public static final int IDLE_TICK_INTERVAL = 40;
public static final int TICK_INTERVAL = 5;
private int tick_timer_;
private int active_timer_;
private int proc_time_elapsed_;
private int time_needed_;
private final RfEnergy.Battery battery_ = new RfEnergy.Battery(energy_max, boost_energy_consumption, 0);
private final LazyOptional<IEnergyStorage> energy_handler_ = battery_.createEnergyHandler();
public BreakerTileEntity(BlockPos pos, BlockState state)
{ super(ModContent.getBlockEntityTypeOfBlock(state.getBlock()), pos, state); }
public void block_updated()
{ if(tick_timer_ > 2) tick_timer_ = 2; }
public void readnbt(CompoundTag nbt)
{ battery_.load(nbt); }
private void writenbt(CompoundTag nbt)
{ battery_.save(nbt); }
public void state_message(Player player)
{
String progress = "0";
if((proc_time_elapsed_ > 0) && (time_needed_ > 0)) {
progress = Integer.toString((int)Mth.clamp((((double)proc_time_elapsed_) / ((double)time_needed_) * 100), 0, 100));
}
Overlay.show(player, Auxiliaries.localizable("block.engineersdecor.small_block_breaker.status", battery_.getSOC(), energy_max, progress));
}
// BlockEntity ------------------------------------------------------------------------------
@Override
public void load(CompoundTag nbt)
{ super.load(nbt); readnbt(nbt); }
@Override
protected void saveAdditional(CompoundTag nbt)
{ super.saveAdditional(nbt); writenbt(nbt); }
@Override
public void setRemoved()
{
super.setRemoved();
energy_handler_.invalidate();
}
// Capability export ----------------------------------------------------------------------------
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if(capability == ForgeCapabilities.ENERGY) return energy_handler_.cast();
return super.getCapability(capability, facing);
}
// ITickable ------------------------------------------------------------------------------------
private static final HashSet<Block> blacklist = new HashSet<>();
static {
blacklist.add(Blocks.AIR);
blacklist.add(Blocks.BEDROCK);
@ -250,18 +192,29 @@ public class EdBreaker
blacklist.add(Blocks.BARRIER);
}
private static boolean isBreakable(BlockState state, BlockPos pos, Level world)
{
private final RfEnergy.Battery battery_ = new RfEnergy.Battery(energy_max, boost_energy_consumption, 0);
private final LazyOptional<IEnergyStorage> energy_handler_ = battery_.createEnergyHandler();
private int tick_timer_;
private int active_timer_;
private int proc_time_elapsed_;
private int time_needed_;
public BreakerTileEntity(BlockPos pos, BlockState state) {
super(ModContent.getBlockEntityTypeOfBlock(state.getBlock()), pos, state);
}
private static boolean isBreakable(BlockState state, BlockPos pos, Level world) {
final Block block = state.getBlock();
if (blacklist.contains(block)) return false;
if (state.isAir()) return false;
if(state.getMaterial().isLiquid()) return false;
if (state.getBlock() instanceof LiquidBlock) return false;
float bh = state.getDestroySpeed(world, pos);
return !((bh < 0) || (bh > 55));
}
private static void spawnBlockAsEntity(Level world, BlockPos pos, ItemStack stack) {
if(world.isClientSide || stack.isEmpty() || (!world.getGameRules().getBoolean(GameRules.RULE_DOBLOCKDROPS)) || world.restoringBlockSnapshots) return;
if (world.isClientSide || stack.isEmpty() || (!world.getGameRules().getBoolean(GameRules.RULE_DOBLOCKDROPS)) || world.restoringBlockSnapshots)
return;
ItemEntity e = new ItemEntity(world,
((world.random.nextFloat() * 0.1) + 0.5) + pos.getX(),
((world.random.nextFloat() * 0.1) + 0.5) + pos.getY(),
@ -273,17 +226,66 @@ public class EdBreaker
world.addFreshEntity(e);
}
private static boolean canInsertInto(Level world, BlockPos pos)
{
// BlockEntity ------------------------------------------------------------------------------
private static boolean canInsertInto(Level world, BlockPos pos) {
// Maybe make a tag for that. The question is if it is actually worth it, or if that would be only
// tag spamming the game. So for now only FH and VH.
final BlockState state = world.getBlockState(pos);
return (state.getBlock() == ModContent.getBlock("factory_hopper")) || (state.getBlock() == Blocks.HOPPER);
}
private boolean breakBlock(BlockState state, BlockPos pos, Level world)
{
if(world.isClientSide || (!(world instanceof ServerLevel)) || world.restoringBlockSnapshots) return false; // retry next cycle
public void block_updated() {
if (tick_timer_ > 2) tick_timer_ = 2;
}
public void readnbt(CompoundTag nbt) {
battery_.load(nbt);
}
// Capability export ----------------------------------------------------------------------------
private void writenbt(CompoundTag nbt) {
battery_.save(nbt);
}
// ITickable ------------------------------------------------------------------------------------
public void state_message(Player player) {
String progress = "0";
if ((proc_time_elapsed_ > 0) && (time_needed_ > 0)) {
progress = Integer.toString((int) Mth.clamp((((double) proc_time_elapsed_) / ((double) time_needed_) * 100), 0, 100));
}
Overlay.show(player, Auxiliaries.localizable("block.engineersdecor.small_block_breaker.status", battery_.getSOC(), energy_max, progress));
}
@Override
public void load(CompoundTag nbt) {
super.load(nbt);
readnbt(nbt);
}
@Override
protected void saveAdditional(CompoundTag nbt) {
super.saveAdditional(nbt);
writenbt(nbt);
}
@Override
public void setRemoved() {
super.setRemoved();
energy_handler_.invalidate();
}
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing) {
if (capability == ForgeCapabilities.ENERGY) return energy_handler_.cast();
return super.getCapability(capability, facing);
}
private boolean breakBlock(BlockState state, BlockPos pos, Level world) {
if (world.isClientSide || (!(world instanceof ServerLevel)) || world.restoringBlockSnapshots)
return false; // retry next cycle
List<ItemStack> drops;
final Block block = state.getBlock();
final boolean insert = canInsertInto(world, getBlockPos().below());
@ -298,14 +300,14 @@ public class EdBreaker
}
}
SoundType stype = state.getBlock().getSoundType(state, world, pos, null);
if(stype != null) world.playSound(null, pos, stype.getPlaceSound(), SoundSource.BLOCKS, stype.getVolume()*0.6f, stype.getPitch());
if (stype != null)
world.playSound(null, pos, stype.getPlaceSound(), SoundSource.BLOCKS, stype.getVolume() * 0.6f, stype.getPitch());
return true;
}
@Override
@SuppressWarnings("deprecation")
public void tick()
{
public void tick() {
if (--tick_timer_ > 0) return;
tick_timer_ = TICK_INTERVAL;
final BlockState device_state = level.getBlockState(worldPosition);
@ -313,7 +315,8 @@ public class EdBreaker
final BlockPos target_pos = worldPosition.relative(device_state.getValue(BreakerBlock.HORIZONTAL_FACING));
final BlockState target_state = level.getBlockState(target_pos);
if ((level.hasNeighborSignal(worldPosition)) || (!isBreakable(target_state, target_pos, level))) {
if(device_state.getValue(BreakerBlock.ACTIVE)) level.setBlock(worldPosition, device_state.setValue(BreakerBlock.ACTIVE, false), 1|2);
if (device_state.getValue(BreakerBlock.ACTIVE))
level.setBlock(worldPosition, device_state.setValue(BreakerBlock.ACTIVE, false), 1 | 2);
proc_time_elapsed_ = 0;
tick_timer_ = IDLE_TICK_INTERVAL;
return;

View file

@ -8,6 +8,8 @@
*/
package dev.zontreck.engineerdecor.blocks;
import dev.zontreck.libzontreck.edlibmc.Inventories;
import dev.zontreck.libzontreck.edlibmc.StandardBlocks;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.sounds.SoundEvents;
@ -31,8 +33,6 @@ import net.minecraft.world.level.material.Fluids;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
import dev.zontreck.engineerdecor.libmc.StandardBlocks;
import dev.zontreck.engineerdecor.libmc.Inventories;
import javax.annotation.Nullable;
import java.util.ArrayList;
@ -41,25 +41,17 @@ import java.util.Collections;
import java.util.List;
public class EdCatwalkBlock extends StandardBlocks.HorizontalFourWayWaterLoggable
{
public class EdCatwalkBlock extends StandardBlocks.HorizontalFourWayWaterLoggable {
final Block railing_block;
final AABB base_aabb;
public EdCatwalkBlock(long config, BlockBehaviour.Properties properties, final AABB base_aabb, final AABB railing_aabb, final Block railing_block)
{ super(config, properties, base_aabb, railing_aabb, 0); this.railing_block = railing_block; this.base_aabb=base_aabb; }
public EdCatwalkBlock(long config, BlockBehaviour.Properties properties, final AABB base_aabb, final AABB railing_aabb, final Block railing_block) {
super(config, properties, base_aabb, railing_aabb, 0);
this.railing_block = railing_block;
this.base_aabb = base_aabb;
}
@Override
public boolean propagatesSkylightDown(BlockState state, BlockGetter reader, BlockPos pos)
{ return true; }
@Override
@Nullable
public BlockState getStateForPlacement(BlockPlaceContext context)
{ return super.getStateForPlacement(context).setValue(NORTH, false).setValue(EAST, false).setValue(SOUTH, false).setValue(WEST, false); }
public static boolean place_consume(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, int shrink)
{
public static boolean place_consume(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, int shrink) {
if (!world.setBlock(pos, state, Block.UPDATE_ALL)) return false;
world.playSound(player, pos, SoundEvents.METAL_PLACE, SoundSource.BLOCKS, 1f, 1f);
if ((!player.isCreative()) && (!world.isClientSide())) {
@ -76,15 +68,26 @@ public class EdCatwalkBlock extends StandardBlocks.HorizontalFourWayWaterLoggabl
return true;
}
@Override
public boolean propagatesSkylightDown(BlockState state, BlockGetter reader, BlockPos pos) {
return true;
}
@Override
@Nullable
public BlockState getStateForPlacement(BlockPlaceContext context) {
return super.getStateForPlacement(context).setValue(NORTH, false).setValue(EAST, false).setValue(SOUTH, false).setValue(WEST, false);
}
@Override
@SuppressWarnings("deprecation")
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit)
{
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
final Item item = player.getItemInHand(hand).getItem();
if ((!(item instanceof BlockItem))) return InteractionResult.PASS;
final Block block = ((BlockItem) item).getBlock();
if (block == this) {
if(hit.getDirection().getAxis().isHorizontal()) return InteractionResult.PASS; // place new block on the clicked side.
if (hit.getDirection().getAxis().isHorizontal())
return InteractionResult.PASS; // place new block on the clicked side.
BlockPos adjacent_pos = pos.relative(player.getDirection());
BlockState adjacent_state = world.getBlockState(adjacent_pos);
if (adjacent_state.canBeReplaced(new DirectionalPlaceContext(world, adjacent_pos, hit.getDirection().getOpposite(), player.getItemInHand(hand), hit.getDirection()))) {
@ -99,7 +102,8 @@ public class EdCatwalkBlock extends StandardBlocks.HorizontalFourWayWaterLoggabl
final Vec3 rhv = hit.getLocation().subtract(Vec3.atCenterOf(hit.getBlockPos()));
if (face.getAxis().isHorizontal()) {
// Side or railing clicked
if(rhv.multiply(Vec3.atLowerCornerOf(face.getNormal())).scale(2).lengthSqr() < 0.99) face = face.getOpposite(); // click on railing, not the outer side.
if (rhv.multiply(Vec3.atLowerCornerOf(face.getNormal())).scale(2).lengthSqr() < 0.99)
face = face.getOpposite(); // click on railing, not the outer side.
} else if (player.distanceToSqr(Vec3.atCenterOf(pos)) < 3) {
// near accurate placement
face = Direction.getNearest(rhv.x, 0, rhv.z);
@ -119,12 +123,12 @@ public class EdCatwalkBlock extends StandardBlocks.HorizontalFourWayWaterLoggabl
}
@Override
public boolean hasDynamicDropList()
{ return true; }
public boolean hasDynamicDropList() {
return true;
}
@Override
public List<ItemStack> dropList(BlockState state, Level world, @Nullable BlockEntity te, boolean explosion)
{
public List<ItemStack> dropList(BlockState state, Level world, @Nullable BlockEntity te, boolean explosion) {
if (world.isClientSide()) return Collections.singletonList(ItemStack.EMPTY);
List<ItemStack> drops = new ArrayList<>();
drops.add(new ItemStack(state.getBlock().asItem()));

View file

@ -8,6 +8,9 @@
*/
package dev.zontreck.engineerdecor.blocks;
import dev.zontreck.engineerdecor.ModContent;
import dev.zontreck.libzontreck.edlibmc.Auxiliaries;
import dev.zontreck.libzontreck.edlibmc.StandardBlocks;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.InteractionHand;
@ -34,24 +37,19 @@ import net.minecraft.world.phys.shapes.BooleanOp;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import dev.zontreck.engineerdecor.ModContent;
import dev.zontreck.engineerdecor.libmc.StandardBlocks;
import dev.zontreck.engineerdecor.libmc.Auxiliaries;
import javax.annotation.Nullable;
import java.util.*;
public class EdCatwalkStairsBlock extends StandardBlocks.HorizontalWaterLoggable
{
public class EdCatwalkStairsBlock extends StandardBlocks.HorizontalWaterLoggable {
public static final BooleanProperty RIGHT_RAILING = BooleanProperty.create("right_railing");
public static final BooleanProperty LEFT_RAILING = BooleanProperty.create("left_railing");
protected final Map<BlockState, VoxelShape> shapes;
protected final Map<BlockState, VoxelShape> collision_shapes;
protected final Map<Direction, Integer> y_rotations;
public EdCatwalkStairsBlock(long config, BlockBehaviour.Properties properties, final AABB[] base_aabb, final AABB[] railing_aabbs)
{
public EdCatwalkStairsBlock(long config, BlockBehaviour.Properties properties, final AABB[] base_aabb, final AABB[] railing_aabbs) {
super(config, properties, base_aabb);
Map<BlockState, VoxelShape> sh = new HashMap<>();
Map<BlockState, VoxelShape> csh = new HashMap<>();
@ -82,30 +80,35 @@ public class EdCatwalkStairsBlock extends StandardBlocks.HorizontalWaterLoggable
}
@Override
public VoxelShape getShape(BlockState state, BlockGetter worldIn, BlockPos pos, CollisionContext context)
{ return shapes.getOrDefault(state, Shapes.block()); }
public VoxelShape getShape(BlockState state, BlockGetter worldIn, BlockPos pos, CollisionContext context) {
return shapes.getOrDefault(state, Shapes.block());
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockGetter worldIn, BlockPos pos, CollisionContext context)
{ return collision_shapes.getOrDefault(state, Shapes.block()); }
public VoxelShape getCollisionShape(BlockState state, BlockGetter worldIn, BlockPos pos, CollisionContext context) {
return collision_shapes.getOrDefault(state, Shapes.block());
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder)
{ super.createBlockStateDefinition(builder); builder.add(RIGHT_RAILING, LEFT_RAILING); }
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
super.createBlockStateDefinition(builder);
builder.add(RIGHT_RAILING, LEFT_RAILING);
}
@Override
public boolean propagatesSkylightDown(BlockState state, BlockGetter reader, BlockPos pos)
{ return true; }
public boolean propagatesSkylightDown(BlockState state, BlockGetter reader, BlockPos pos) {
return true;
}
@Override
@Nullable
public BlockState getStateForPlacement(BlockPlaceContext context)
{ return super.getStateForPlacement(context); }
public BlockState getStateForPlacement(BlockPlaceContext context) {
return super.getStateForPlacement(context);
}
@Override
@SuppressWarnings("deprecation")
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit)
{
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
final Item item = player.getItemInHand(hand).getItem();
if ((!(item instanceof BlockItem))) return InteractionResult.PASS;
final Block block = ((BlockItem) item).getBlock();
@ -121,8 +124,10 @@ public class EdCatwalkStairsBlock extends StandardBlocks.HorizontalWaterLoggable
return world.isClientSide() ? InteractionResult.SUCCESS : InteractionResult.CONSUME;
}
final BlockState adjacent_state = world.getBlockState(adjacent_pos);
if(adjacent_state == null) return world.isClientSide() ? InteractionResult.SUCCESS : InteractionResult.CONSUME;
if(!adjacent_state.canBeReplaced(new DirectionalPlaceContext(world, adjacent_pos, hit.getDirection().getOpposite(), player.getItemInHand(hand), hit.getDirection()))) return InteractionResult.CONSUME;
if (adjacent_state == null)
return world.isClientSide() ? InteractionResult.SUCCESS : InteractionResult.CONSUME;
if (!adjacent_state.canBeReplaced(new DirectionalPlaceContext(world, adjacent_pos, hit.getDirection().getOpposite(), player.getItemInHand(hand), hit.getDirection())))
return InteractionResult.CONSUME;
BlockState place_state = defaultBlockState().setValue(HORIZONTAL_FACING, facing);
place_state = place_state.setValue(WATERLOGGED, adjacent_state.getFluidState().getType() == Fluids.WATER);
EdCatwalkBlock.place_consume(place_state, world, adjacent_pos, player, hand, 1);
@ -132,7 +137,8 @@ public class EdCatwalkStairsBlock extends StandardBlocks.HorizontalWaterLoggable
adjacent_pos = pos.relative(facing);
final BlockState adjacent_state = world.getBlockState(adjacent_pos);
if (adjacent_state == null) return InteractionResult.CONSUME;
if(!adjacent_state.canBeReplaced(new DirectionalPlaceContext(world, adjacent_pos, hit.getDirection().getOpposite(), player.getItemInHand(hand), hit.getDirection()))) return InteractionResult.CONSUME;
if (!adjacent_state.canBeReplaced(new DirectionalPlaceContext(world, adjacent_pos, hit.getDirection().getOpposite(), player.getItemInHand(hand), hit.getDirection())))
return InteractionResult.CONSUME;
BlockState place_state = ModContent.getBlock("steel_catwalk_ta").defaultBlockState(); // ModContent.STEEL_CATWALK_TOP_ALIGNED
place_state = place_state.setValue(WATERLOGGED, adjacent_state.getFluidState().getType() == Fluids.WATER);
EdCatwalkBlock.place_consume(place_state, world, adjacent_pos, player, hand, 1);
@ -169,12 +175,12 @@ public class EdCatwalkStairsBlock extends StandardBlocks.HorizontalWaterLoggable
}
@Override
public boolean hasDynamicDropList()
{ return true; }
public boolean hasDynamicDropList() {
return true;
}
@Override
public List<ItemStack> dropList(BlockState state, Level world, @Nullable BlockEntity te, boolean explosion)
{
public List<ItemStack> dropList(BlockState state, Level world, @Nullable BlockEntity te, boolean explosion) {
if (world.isClientSide()) return Collections.singletonList(ItemStack.EMPTY);
List<ItemStack> drops = new ArrayList<>();
drops.add(new ItemStack(state.getBlock().asItem()));

View file

@ -8,6 +8,8 @@
*/
package dev.zontreck.engineerdecor.blocks;
import dev.zontreck.engineerdecor.ModContent;
import dev.zontreck.libzontreck.edlibmc.StandardBlocks;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.InteractionHand;
@ -32,8 +34,6 @@ import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import dev.zontreck.engineerdecor.ModContent;
import dev.zontreck.engineerdecor.libmc.StandardBlocks;
import javax.annotation.Nullable;
import java.util.ArrayList;
@ -42,14 +42,12 @@ import java.util.List;
import java.util.stream.Collectors;
public class EdCatwalkTopAlignedBlock extends StandardBlocks.WaterLoggable
{
public class EdCatwalkTopAlignedBlock extends StandardBlocks.WaterLoggable {
public static final IntegerProperty VARIANT = IntegerProperty.create("variant", 0, 4);
protected final List<VoxelShape> variant_shapes;
protected final Block inset_light_block;
public EdCatwalkTopAlignedBlock(long config, BlockBehaviour.Properties properties, final VoxelShape[] variant_shapes, final Block inset_light_block)
{
public EdCatwalkTopAlignedBlock(long config, BlockBehaviour.Properties properties, final VoxelShape[] variant_shapes, final Block inset_light_block) {
super(config, properties, variant_shapes[0]);
registerDefaultState(super.defaultBlockState().setValue(VARIANT, 0));
this.variant_shapes = VARIANT.getPossibleValues().stream().map(i -> (i < variant_shapes.length) ? (variant_shapes[i]) : (Shapes.block())).collect(Collectors.toList());
@ -57,36 +55,40 @@ public class EdCatwalkTopAlignedBlock extends StandardBlocks.WaterLoggable
}
@Override
public boolean propagatesSkylightDown(BlockState state, BlockGetter reader, BlockPos pos)
{ return true; }
public boolean propagatesSkylightDown(BlockState state, BlockGetter reader, BlockPos pos) {
return true;
}
@Override
public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext)
{ return variant_shapes.get(state.getValue(VARIANT)); }
public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) {
return variant_shapes.get(state.getValue(VARIANT));
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext)
{ return getShape(state, world, pos, selectionContext); }
public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) {
return getShape(state, world, pos, selectionContext);
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder)
{ super.createBlockStateDefinition(builder); builder.add(VARIANT); }
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
super.createBlockStateDefinition(builder);
builder.add(VARIANT);
}
@Override
@Nullable
public BlockState getStateForPlacement(BlockPlaceContext context)
{
public BlockState getStateForPlacement(BlockPlaceContext context) {
BlockState state = adapted_state(super.getStateForPlacement(context), context.getLevel(), context.getClickedPos());
if (context.getClickedFace() != Direction.UP) return state;
BlockState below = context.getLevel().getBlockState(context.getClickedPos().below());
if((state.getValue(VARIANT)==0) && (below.isFaceSturdy(context.getLevel(), context.getClickedPos().below(), Direction.UP))) return state.setValue(VARIANT, 3);
if ((state.getValue(VARIANT) == 0) && (below.isFaceSturdy(context.getLevel(), context.getClickedPos().below(), Direction.UP)))
return state.setValue(VARIANT, 3);
return state;
}
@Override
@SuppressWarnings("deprecation")
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit)
{
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
final Item item = player.getItemInHand(hand).getItem();
if ((!(item instanceof BlockItem))) return InteractionResult.PASS;
final Block block = ((BlockItem) item).getBlock();
@ -112,17 +114,19 @@ public class EdCatwalkTopAlignedBlock extends StandardBlocks.WaterLoggable
}
@Override
public BlockState updateShape(BlockState state, Direction facing, BlockState facingState, LevelAccessor world, BlockPos pos, BlockPos facingPos)
{ return adapted_state(super.updateShape(state, facing, facingState, world, pos, facingPos), world, pos); }
public BlockState updateShape(BlockState state, Direction facing, BlockState facingState, LevelAccessor world, BlockPos pos, BlockPos facingPos) {
return adapted_state(super.updateShape(state, facing, facingState, world, pos, facingPos), world, pos);
}
// ---
private BlockState adapted_state(BlockState state, LevelAccessor world, BlockPos pos)
{
private BlockState adapted_state(BlockState state, LevelAccessor world, BlockPos pos) {
BlockState below = world.getBlockState(pos.below());
if (state == null || state.getValue(VARIANT) == 4) return state;
if((below.getBlock() == ModContent.getBlock("thick_steel_pole")) || (below.getBlock() == ModContent.getBlock("thick_steel_pole_head"))) return state.setValue(VARIANT, 1);
if((below.getBlock() == ModContent.getBlock("thin_steel_pole")) || (below.getBlock() == ModContent.getBlock("thin_steel_pole_head"))) return state.setValue(VARIANT, 2);
if ((below.getBlock() == ModContent.getBlock("thick_steel_pole")) || (below.getBlock() == ModContent.getBlock("thick_steel_pole_head")))
return state.setValue(VARIANT, 1);
if ((below.getBlock() == ModContent.getBlock("thin_steel_pole")) || (below.getBlock() == ModContent.getBlock("thin_steel_pole_head")))
return state.setValue(VARIANT, 2);
return state;
}
@ -134,12 +138,12 @@ public class EdCatwalkTopAlignedBlock extends StandardBlocks.WaterLoggable
}
@Override
public boolean hasDynamicDropList()
{ return true; }
public boolean hasDynamicDropList() {
return true;
}
@Override
public List<ItemStack> dropList(BlockState state, Level world, @Nullable BlockEntity te, boolean explosion)
{
public List<ItemStack> dropList(BlockState state, Level world, @Nullable BlockEntity te, boolean explosion) {
if (world.isClientSide()) return Collections.singletonList(ItemStack.EMPTY);
List<ItemStack> drops = new ArrayList<>();
drops.add(new ItemStack(state.getBlock().asItem()));

View file

@ -8,9 +8,13 @@
*/
package dev.zontreck.engineerdecor.blocks;
import dev.zontreck.engineerdecor.ModConfig;
import dev.zontreck.engineerdecor.ModContent;
import dev.zontreck.libzontreck.edlibmc.StandardBlocks;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ClientGamePacketListener;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.Mth;
import net.minecraft.util.RandomSource;
@ -29,23 +33,18 @@ import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.network.PlayMessages;
import net.minecraftforge.network.NetworkHooks;
import dev.zontreck.engineerdecor.ModConfig;
import dev.zontreck.engineerdecor.ModContent;
import dev.zontreck.engineerdecor.libmc.StandardBlocks;
import net.minecraftforge.network.PlayMessages;
import java.util.List;
public class EdChair
{
public class EdChair {
private static boolean sitting_enabled = true;
private static double sitting_probability = 0.1;
private static double standup_probability = 0.01;
public static void on_config(boolean without_sitting, boolean without_mob_sitting, double sitting_probability_percent, double standup_probability_percent)
{
public static void on_config(boolean without_sitting, boolean without_mob_sitting, double sitting_probability_percent, double standup_probability_percent) {
sitting_enabled = (!without_sitting);
sitting_probability = (without_sitting || without_mob_sitting) ? 0.0 : Mth.clamp(sitting_probability_percent / 100, 0, 0.9);
standup_probability = (without_sitting || without_mob_sitting) ? 1.0 : Mth.clamp(standup_probability_percent / 100, 1e-6, 1e-2);
@ -56,15 +55,14 @@ public class EdChair
// Block
//--------------------------------------------------------------------------------------------------------------------
public static class ChairBlock extends StandardBlocks.HorizontalWaterLoggable
{
public ChairBlock(long config, BlockBehaviour.Properties builder, final AABB[] unrotatedAABBs)
{ super(config, builder.randomTicks(), unrotatedAABBs); }
public static class ChairBlock extends StandardBlocks.HorizontalWaterLoggable {
public ChairBlock(long config, BlockBehaviour.Properties builder, final AABB[] unrotatedAABBs) {
super(config, builder.randomTicks(), unrotatedAABBs);
}
@Override
@SuppressWarnings("deprecation")
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult rayTraceResult)
{
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult rayTraceResult) {
if (!sitting_enabled) return InteractionResult.PASS;
if (world.isClientSide()) return InteractionResult.SUCCESS;
EntityChair.sit(world, player, pos);
@ -73,15 +71,14 @@ public class EdChair
@Override
@SuppressWarnings("deprecation")
public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity)
{
if(sitting_enabled && (Math.random() < sitting_probability) && (entity instanceof Mob)) EntityChair.sit(world, (LivingEntity)entity, pos);
public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
if (sitting_enabled && (Math.random() < sitting_probability) && (entity instanceof Mob))
EntityChair.sit(world, (LivingEntity) entity, pos);
}
@Override
@SuppressWarnings("deprecation")
public void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource rnd)
{
public void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource rnd) {
if ((!sitting_enabled) || (sitting_probability < 1e-6)) return;
final List<Mob> entities = world.getEntitiesOfClass(Mob.class, new AABB(pos).inflate(2, 1, 2).expandTowards(0, 1, 0), e -> true);
if (entities.isEmpty()) return;
@ -95,16 +92,14 @@ public class EdChair
// Entity
//--------------------------------------------------------------------------------------------------------------------
public static class EntityChair extends Entity
{
public static class EntityChair extends Entity {
public static final double x_offset = 0.5d;
public static final double y_offset = 0.4d;
public static final double z_offset = 0.5d;
private int t_sit = 0;
public BlockPos chair_pos = new BlockPos(0, 0, 0);
private int t_sit = 0;
public EntityChair(EntityType<? extends Entity> entityType, Level world)
{
public EntityChair(EntityType<? extends Entity> entityType, Level world) {
super(entityType, world);
blocksBuilding = true;
setDeltaMovement(Vec3.ZERO);
@ -112,19 +107,18 @@ public class EdChair
noPhysics = true;
}
public EntityChair(Level world)
{ this(ModContent.getEntityType("et_chair"), world); }
public EntityChair(Level world) {
this(ModContent.getEntityType("et_chair"), world);
}
public static EntityChair customClientFactory(PlayMessages.SpawnEntity spkt, Level world)
{ return new EntityChair(world); }
public static EntityChair customClientFactory(PlayMessages.SpawnEntity spkt, Level world) {
return new EntityChair(world);
}
public Packet<?> getAddEntityPacket()
{ return NetworkHooks.getEntitySpawningPacket(this); }
public static boolean accepts_mob(LivingEntity entity)
{
public static boolean accepts_mob(LivingEntity entity) {
if (!(entity instanceof Monster)) return false;
if((entity.getType().getDimensions().height > 2.5) || (entity.getType().getDimensions().height > 2.0)) return false;
if ((entity.getType().getDimensions().height > 2.5) || (entity.getType().getDimensions().height > 2.0))
return false;
if (entity instanceof Zombie) return true;
if (entity instanceof ZombieVillager) return true;
if (entity instanceof ZombifiedPiglin) return true;
@ -136,8 +130,7 @@ public class EdChair
return false;
}
public static void sit(Level world, LivingEntity sitter, BlockPos pos)
{
public static void sit(Level world, LivingEntity sitter, BlockPos pos) {
if (!sitting_enabled) return;
if ((world == null) || (world.isClientSide) || (sitter == null) || (pos == null)) return;
if ((!(sitter instanceof Player)) && (!accepts_mob(sitter))) return;
@ -158,27 +151,35 @@ public class EdChair
sitter.startRiding(chair, true);
}
@Override
protected void defineSynchedData() {}
public Packet<ClientGamePacketListener> getAddEntityPacket() {
return NetworkHooks.getEntitySpawningPacket(this);
}
@Override
protected void readAdditionalSaveData(CompoundTag compound) {}
protected void defineSynchedData() {
}
@Override
protected void addAdditionalSaveData(CompoundTag compound) {}
protected void readAdditionalSaveData(CompoundTag compound) {
}
@Override
public boolean isPushable()
{ return false; }
protected void addAdditionalSaveData(CompoundTag compound) {
}
@Override
public double getPassengersRidingOffset()
{ return 0.0; }
public boolean isPushable() {
return false;
}
@Override
public void tick()
{
if(level.isClientSide) return;
public double getPassengersRidingOffset() {
return 0.0;
}
@Override
public void tick() {
if (level().isClientSide) return;
super.tick();
if (--t_sit > 0) return;
Entity sitter = getPassengers().isEmpty() ? null : getPassengers().get(0);
@ -187,9 +188,9 @@ public class EdChair
return;
}
boolean abort = (!sitting_enabled);
final BlockState state = level.getBlockState(chair_pos);
final BlockState state = level().getBlockState(chair_pos);
if ((state == null) || (!(state.getBlock() instanceof ChairBlock))) abort = true;
if(!level.isEmptyBlock(chair_pos.above())) abort = true;
if (!level().isEmptyBlock(chair_pos.above())) abort = true;
if ((!(sitter instanceof Player)) && (Math.random() < standup_probability)) abort = true;
if (abort) {
for (Entity e : getPassengers()) {

View file

@ -8,6 +8,7 @@
*/
package dev.zontreck.engineerdecor.blocks;
import dev.zontreck.libzontreck.edlibmc.StandardBlocks;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.particles.ParticleTypes;
@ -17,7 +18,7 @@ import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.SignalGetter;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState;
@ -28,31 +29,30 @@ import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import dev.zontreck.engineerdecor.libmc.StandardBlocks;
import javax.annotation.Nullable;
public class EdChimneyBlock extends StandardBlocks.Cutout
{
public class EdChimneyBlock extends StandardBlocks.Cutout {
public static final IntegerProperty POWER = BlockStateProperties.POWER;
public EdChimneyBlock(long config, BlockBehaviour.Properties properties, AABB aabb)
{ super(config, properties, aabb); }
public EdChimneyBlock(long config, BlockBehaviour.Properties properties, AABB aabb) {
super(config, properties, aabb);
}
public EdChimneyBlock(long config, BlockBehaviour.Properties builder)
{
public EdChimneyBlock(long config, BlockBehaviour.Properties builder) {
this(config, builder, new AABB(0, 0, 0, 1, 1, 1));
registerDefaultState(super.defaultBlockState().setValue(POWER, 0)); // no smoke in JEI
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder)
{ super.createBlockStateDefinition(builder); builder.add(POWER); }
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
super.createBlockStateDefinition(builder);
builder.add(POWER);
}
@Override
@Nullable
public BlockState getStateForPlacement(BlockPlaceContext context)
{
public BlockState getStateForPlacement(BlockPlaceContext context) {
BlockState state = super.getStateForPlacement(context);
if (state == null) return state;
int p = context.getLevel().getBestNeighborSignal(context.getClickedPos());
@ -61,25 +61,26 @@ public class EdChimneyBlock extends StandardBlocks.Cutout
@Override
@SuppressWarnings("deprecation")
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult rayTraceResult)
{ world.setBlock(pos, state.setValue(POWER, (state.getValue(POWER)+1) & 0xf), 1|2); return InteractionResult.sidedSuccess(world.isClientSide()); }
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult rayTraceResult) {
world.setBlock(pos, state.setValue(POWER, (state.getValue(POWER) + 1) & 0xf), 1 | 2);
return InteractionResult.sidedSuccess(world.isClientSide());
}
@Override
@SuppressWarnings("deprecation")
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block block, BlockPos fromPos, boolean unused)
{
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block block, BlockPos fromPos, boolean unused) {
int p = world.getBestNeighborSignal(pos);
if (p != state.getValue(POWER)) world.setBlock(pos, state.setValue(POWER, p), 2);
}
@Override
public boolean shouldCheckWeakPower(BlockState state, LevelReader world, BlockPos pos, Direction side)
{ return false; }
public boolean shouldCheckWeakPower(BlockState state, SignalGetter level, BlockPos pos, Direction side) {
return false;
}
@Override
@OnlyIn(Dist.CLIENT)
public void animateTick(BlockState state, Level world, BlockPos pos, RandomSource rnd)
{
public void animateTick(BlockState state, Level world, BlockPos pos, RandomSource rnd) {
if (state.getBlock() != this) return;
final int p = state.getValue(POWER);
if (p == 0) return;

View file

@ -19,18 +19,18 @@ import net.minecraft.world.phys.shapes.VoxelShape;
import javax.annotation.Nullable;
public class EdChimneyTrunkBlock extends EdRoofBlock
{
public EdChimneyTrunkBlock(long config, BlockBehaviour.Properties properties)
{ super(config, properties.dynamicShape(), Shapes.empty(), Shapes.empty()); }
public class EdChimneyTrunkBlock extends EdRoofBlock {
public EdChimneyTrunkBlock(long config, BlockBehaviour.Properties properties) {
super(config, properties.dynamicShape(), Shapes.empty(), Shapes.empty());
}
public EdChimneyTrunkBlock(long config, BlockBehaviour.Properties properties, VoxelShape add, VoxelShape cut)
{ super(config, properties, add, cut); }
public EdChimneyTrunkBlock(long config, BlockBehaviour.Properties properties, VoxelShape add, VoxelShape cut) {
super(config, properties, add, cut);
}
@Override
@Nullable
public BlockState getStateForPlacement(BlockPlaceContext context)
{
public BlockState getStateForPlacement(BlockPlaceContext context) {
BlockState state = super.getStateForPlacement(context);
return (state == null) ? (state) : (state.setValue(EdRoofBlock.SHAPE, StairsShape.STRAIGHT).setValue(EdRoofBlock.HALF, Half.BOTTOM));
}

View file

@ -8,6 +8,8 @@
*/
package dev.zontreck.engineerdecor.blocks;
import dev.zontreck.libzontreck.edlibmc.Auxiliaries;
import dev.zontreck.libzontreck.edlibmc.StandardBlocks;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.util.Mth;
@ -17,28 +19,23 @@ import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec2;
import dev.zontreck.engineerdecor.libmc.StandardBlocks;
import dev.zontreck.engineerdecor.libmc.Auxiliaries;
import javax.annotation.Nullable;
import java.util.Arrays;
import java.util.HashSet;
public class EdCornerOrnamentedBlock extends StandardBlocks.Directed
{
public class EdCornerOrnamentedBlock extends StandardBlocks.Directed {
protected final HashSet<Block> compatible_blocks;
public EdCornerOrnamentedBlock(long config, BlockBehaviour.Properties properties, Block[] assigned_wall_blocks)
{
public EdCornerOrnamentedBlock(long config, BlockBehaviour.Properties properties, Block[] assigned_wall_blocks) {
super(config, properties, Auxiliaries.getPixeledAABB(0, 0, 0, 16, 16, 16));
compatible_blocks = new HashSet<>(Arrays.asList(assigned_wall_blocks));
}
@Override
@Nullable
public BlockState getStateForPlacement(BlockPlaceContext context)
{
public BlockState getStateForPlacement(BlockPlaceContext context) {
final Level world = context.getLevel();
final BlockPos pos = context.getClickedPos();
// 1. Placement as below/above for corners, or placement adjacent horizontally if up/down facing.

View file

@ -8,6 +8,8 @@
*/
package dev.zontreck.engineerdecor.blocks;
import dev.zontreck.libzontreck.edlibmc.Auxiliaries;
import dev.zontreck.libzontreck.edlibmc.StandardBlocks;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.sounds.SoundEvents;
@ -32,27 +34,24 @@ import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import dev.zontreck.engineerdecor.libmc.StandardBlocks;
import dev.zontreck.engineerdecor.libmc.Auxiliaries;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
public class EdDoubleGateBlock extends StandardBlocks.HorizontalWaterLoggable
{
public class EdDoubleGateBlock extends StandardBlocks.HorizontalWaterLoggable {
public static final IntegerProperty SEGMENT = IntegerProperty.create("segment", 0, 1);
public static final BooleanProperty OPEN = FenceGateBlock.OPEN;
public static final int SEGMENT_LOWER = 0;
public static final int SEGMENT_UPPER = 1;
protected final ArrayList<VoxelShape> collision_shapes_;
public EdDoubleGateBlock(long config, BlockBehaviour.Properties properties, AABB aabb)
{ this(config, properties, new AABB[]{aabb}); }
public EdDoubleGateBlock(long config, BlockBehaviour.Properties properties, AABB aabb) {
this(config, properties, new AABB[]{aabb});
}
public EdDoubleGateBlock(long config, BlockBehaviour.Properties properties, AABB[] aabbs)
{
public EdDoubleGateBlock(long config, BlockBehaviour.Properties properties, AABB[] aabbs) {
super(config, properties, aabbs);
AABB[] caabbs = new AABB[aabbs.length];
for (int i = 0; i < caabbs.length; ++i) caabbs[i] = aabbs[i].expandTowards(0, 0.5, 0);
@ -69,28 +68,33 @@ public class EdDoubleGateBlock extends StandardBlocks.HorizontalWaterLoggable
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext)
{ return state.getValue(OPEN) ? Shapes.empty() : collision_shapes_.get(state.getValue(HORIZONTAL_FACING).get3DDataValue() & 0x7); }
public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) {
return state.getValue(OPEN) ? Shapes.empty() : collision_shapes_.get(state.getValue(HORIZONTAL_FACING).get3DDataValue() & 0x7);
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder)
{ super.createBlockStateDefinition(builder); builder.add(SEGMENT).add(OPEN); }
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
super.createBlockStateDefinition(builder);
builder.add(SEGMENT).add(OPEN);
}
@Override
@Nullable
public BlockState getStateForPlacement(BlockPlaceContext context)
{ return getInitialState(super.getStateForPlacement(context), context.getLevel(), context.getClickedPos()); }
public BlockState getStateForPlacement(BlockPlaceContext context) {
return getInitialState(super.getStateForPlacement(context), context.getLevel(), context.getClickedPos());
}
@Override
@SuppressWarnings("deprecation")
public BlockState updateShape(BlockState state, Direction facing, BlockState facingState, LevelAccessor world, BlockPos pos, BlockPos facingPos)
{ return getInitialState(super.updateShape(state, facing, facingState, world, pos, facingPos), world, pos); }
public BlockState updateShape(BlockState state, Direction facing, BlockState facingState, LevelAccessor world, BlockPos pos, BlockPos facingPos) {
return getInitialState(super.updateShape(state, facing, facingState, world, pos, facingPos), world, pos);
}
@Override
@SuppressWarnings("deprecation")
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult rayTraceResult)
{
if((rayTraceResult.getDirection()==Direction.UP) || (rayTraceResult.getDirection()==Direction.DOWN) && (player.getItemInHand(hand).getItem()==this.asItem())) return InteractionResult.PASS;
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult rayTraceResult) {
if ((rayTraceResult.getDirection() == Direction.UP) || (rayTraceResult.getDirection() == Direction.DOWN) && (player.getItemInHand(hand).getItem() == this.asItem()))
return InteractionResult.PASS;
if (world.isClientSide()) return InteractionResult.SUCCESS;
final boolean open = !state.getValue(OPEN);
world.setBlock(pos, state.setValue(OPEN, open), 2 | 8 | 16);
@ -107,13 +111,13 @@ public class EdDoubleGateBlock extends StandardBlocks.HorizontalWaterLoggable
@Override
@SuppressWarnings("deprecation")
public boolean isPathfindable(BlockState state, BlockGetter world, BlockPos pos, PathComputationType type)
{ return state.getValue(OPEN); }
public boolean isPathfindable(BlockState state, BlockGetter world, BlockPos pos, PathComputationType type) {
return state.getValue(OPEN);
}
@Override
@SuppressWarnings("deprecation")
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block block, BlockPos fromPos, boolean isMoving)
{
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block block, BlockPos fromPos, boolean isMoving) {
if (world.isClientSide) return;
boolean powered = false;
BlockState adjacent;
@ -153,12 +157,13 @@ public class EdDoubleGateBlock extends StandardBlocks.HorizontalWaterLoggable
// -------------------------------------------------------------------------------------------------------------------
private BlockState getInitialState(BlockState state, LevelAccessor world, BlockPos pos)
{
private BlockState getInitialState(BlockState state, LevelAccessor world, BlockPos pos) {
final BlockState down = world.getBlockState(pos.below());
if(down.getBlock() == this) return state.setValue(SEGMENT, SEGMENT_UPPER).setValue(OPEN, down.getValue(OPEN)).setValue(HORIZONTAL_FACING, down.getValue(HORIZONTAL_FACING));
if (down.getBlock() == this)
return state.setValue(SEGMENT, SEGMENT_UPPER).setValue(OPEN, down.getValue(OPEN)).setValue(HORIZONTAL_FACING, down.getValue(HORIZONTAL_FACING));
final BlockState up = world.getBlockState(pos.above());
if(up.getBlock() == this) return state.setValue(SEGMENT, SEGMENT_LOWER).setValue(OPEN, up.getValue(OPEN)).setValue(HORIZONTAL_FACING, up.getValue(HORIZONTAL_FACING));
if (up.getBlock() == this)
return state.setValue(SEGMENT, SEGMENT_LOWER).setValue(OPEN, up.getValue(OPEN)).setValue(HORIZONTAL_FACING, up.getValue(HORIZONTAL_FACING));
return state.setValue(SEGMENT, SEGMENT_LOWER).setValue(OPEN, false);
}

View file

@ -8,9 +8,10 @@
*/
package dev.zontreck.engineerdecor.blocks;
import com.mojang.blaze3d.vertex.PoseStack;
import dev.zontreck.engineerdecor.libmc.Networking;
import dev.zontreck.engineerdecor.libmc.TooltipDisplay;
import dev.zontreck.engineerdecor.ModConfig;
import dev.zontreck.engineerdecor.ModContent;
import dev.zontreck.libzontreck.edlibmc.*;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
@ -29,7 +30,7 @@ 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.SignalGetter;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockBehaviour;
@ -48,16 +49,6 @@ import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.capabilities.ForgeCapabilities;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.items.IItemHandler;
import dev.zontreck.engineerdecor.ModConfig;
import dev.zontreck.engineerdecor.ModContent;
import dev.zontreck.engineerdecor.libmc.StandardBlocks;
import dev.zontreck.engineerdecor.libmc.StandardEntityBlocks;
import dev.zontreck.engineerdecor.libmc.Auxiliaries;
import dev.zontreck.engineerdecor.libmc.Inventories;
import dev.zontreck.engineerdecor.libmc.Inventories.InventoryRange;
import dev.zontreck.engineerdecor.libmc.Inventories.StorageInventory;
import dev.zontreck.engineerdecor.libmc.RsSignals;
import dev.zontreck.engineerdecor.libmc.Guis;
import javax.annotation.Nullable;
import java.util.ArrayList;
@ -66,12 +57,10 @@ import java.util.Collections;
import java.util.List;
public class EdDropper
{
public class EdDropper {
private static boolean with_adjacent_item_insertion = false;
public static void on_config(boolean with_item_insertion)
{
public static void on_config(boolean with_item_insertion) {
with_adjacent_item_insertion = with_item_insertion;
ModConfig.log("Config dropper: item-insertion:" + with_adjacent_item_insertion + ".");
}
@ -80,47 +69,54 @@ public class EdDropper
// Block
//--------------------------------------------------------------------------------------------------------------------
public static class DropperBlock extends StandardBlocks.Directed implements StandardEntityBlocks.IStandardEntityBlock<DropperTileEntity>
{
public static class DropperBlock extends StandardBlocks.Directed implements StandardEntityBlocks.IStandardEntityBlock<DropperTileEntity> {
public static final BooleanProperty OPEN = BlockStateProperties.OPEN;
public DropperBlock(long config, BlockBehaviour.Properties builder, final AABB unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
public DropperBlock(long config, BlockBehaviour.Properties builder, final AABB unrotatedAABB) {
super(config, builder, unrotatedAABB);
}
@Override
public boolean isBlockEntityTicking(Level world, BlockState state)
{ return true; }
public boolean isBlockEntityTicking(Level world, BlockState state) {
return true;
}
@Override
public RenderTypeHint getRenderTypeHint()
{ return RenderTypeHint.SOLID; }
public RenderTypeHint getRenderTypeHint() {
return RenderTypeHint.SOLID;
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext)
{ return Shapes.block(); }
public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) {
return Shapes.block();
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder)
{ super.createBlockStateDefinition(builder); builder.add(OPEN); }
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
super.createBlockStateDefinition(builder);
builder.add(OPEN);
}
@Override
@Nullable
public BlockState getStateForPlacement(BlockPlaceContext context)
{ return super.getStateForPlacement(context).setValue(OPEN, false); }
public BlockState getStateForPlacement(BlockPlaceContext context) {
return super.getStateForPlacement(context).setValue(OPEN, false);
}
@Override
@SuppressWarnings("deprecation")
public boolean hasAnalogOutputSignal(BlockState state)
{ return true; }
public boolean hasAnalogOutputSignal(BlockState state) {
return true;
}
@Override
@SuppressWarnings("deprecation")
public int getAnalogOutputSignal(BlockState blockState, Level world, BlockPos pos)
{ return (world.getBlockEntity(pos) instanceof DropperTileEntity te) ? RsSignals.fromContainer(te.storage_slot_range_) : 0; }
public int getAnalogOutputSignal(BlockState blockState, Level world, BlockPos pos) {
return (world.getBlockEntity(pos) instanceof DropperTileEntity te) ? RsSignals.fromContainer(te.storage_slot_range_) : 0;
}
@Override
public void setPlacedBy(Level world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack)
{
public void setPlacedBy(Level world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) {
if (world.isClientSide) return;
if ((!stack.hasTag()) || (!stack.getTag().contains("tedata"))) return;
CompoundTag te_nbt = stack.getTag().getCompound("tedata");
@ -133,12 +129,12 @@ public class EdDropper
}
@Override
public boolean hasDynamicDropList()
{ return true; }
public boolean hasDynamicDropList() {
return true;
}
@Override
public List<ItemStack> dropList(BlockState state, Level world, final BlockEntity te, boolean explosion)
{
public List<ItemStack> dropList(BlockState state, Level world, final BlockEntity te, boolean explosion) {
final List<ItemStack> stacks = new ArrayList<>();
if (world.isClientSide) return stacks;
if (!(te instanceof DropperTileEntity)) return stacks;
@ -162,13 +158,13 @@ public class EdDropper
@Override
@SuppressWarnings("deprecation")
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult rayTraceResult)
{ return useOpenGui(state, world, pos, player); }
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult rayTraceResult) {
return useOpenGui(state, world, pos, player);
}
@Override
@SuppressWarnings("deprecation")
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block block, BlockPos fromPos, boolean unused)
{
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block block, BlockPos fromPos, boolean unused) {
if (!(world instanceof Level) || (world.isClientSide)) return;
BlockEntity te = world.getBlockEntity(pos);
if (!(te instanceof DropperTileEntity)) return;
@ -176,16 +172,16 @@ public class EdDropper
}
@Override
public boolean shouldCheckWeakPower(BlockState state, LevelReader world, BlockPos pos, Direction side)
{ return false; }
public boolean shouldCheckWeakPower(BlockState state, SignalGetter level, BlockPos pos, Direction side) {
return false;
}
}
//--------------------------------------------------------------------------------------------------------------------
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
public static class DropperTileEntity extends StandardEntityBlocks.StandardBlockEntity implements MenuProvider, Nameable
{
public static class DropperTileEntity extends StandardEntityBlocks.StandardBlockEntity implements MenuProvider, Nameable {
public static final int NUM_OF_FIELDS = 16;
public static final int TICK_INTERVAL = 32;
public static final int NUM_OF_SLOTS = 15;
@ -203,6 +199,10 @@ public class EdDropper
public static final int DROPLOGIC_SILENT_OPEN = 0x08;
public static final int DROPLOGIC_CONTINUOUS = 0x10;
public static final int DROPLOGIC_IGNORE_EXT = 0x20;
protected final Inventories.StorageInventory main_inventory_ = new Inventories.StorageInventory(this, NUM_OF_SLOTS, 1);
protected final Inventories.InventoryRange storage_slot_range_ = new Inventories.InventoryRange(main_inventory_, INPUT_SLOTS_FIRST, INPUT_SLOTS_SIZE);
protected LazyOptional<? extends IItemHandler> item_handler_ = Inventories.MappedItemHandler.createGenericHandler(storage_slot_range_);
protected final Inventories.InventoryRange filter_slot_range_ = new Inventories.InventoryRange(main_inventory_, CTRL_SLOTS_FIRST, CTRL_SLOTS_SIZE);
///
private final int[] filter_matches_ = new int[CTRL_SLOTS_SIZE];
private int open_timer_ = 0;
@ -218,124 +218,14 @@ public class EdDropper
private int drop_logic_ = DROPLOGIC_EXTERN_ANDGATE;
private int drop_period_ = 0;
private int drop_slot_index_ = 0;
private int tick_timer_ = 0;
protected final Inventories.StorageInventory main_inventory_ = new StorageInventory(this, NUM_OF_SLOTS, 1);
protected final InventoryRange storage_slot_range_ = new InventoryRange(main_inventory_, INPUT_SLOTS_FIRST, INPUT_SLOTS_SIZE);
protected final InventoryRange filter_slot_range_ = new InventoryRange(main_inventory_, CTRL_SLOTS_FIRST, CTRL_SLOTS_SIZE);
protected LazyOptional<? extends IItemHandler> item_handler_ = Inventories.MappedItemHandler.createGenericHandler(storage_slot_range_);
public DropperTileEntity(BlockPos pos, BlockState state)
{ super(ModContent.getBlockEntityTypeOfBlock(state.getBlock()), pos, state); reset_rtstate(); }
public CompoundTag clear_getnbt()
{
CompoundTag nbt = new CompoundTag();
writenbt(nbt, false);
main_inventory_.clearContent();
reset_rtstate();
triggered_ = false;
block_power_updated_ = false;
return nbt;
protected final ContainerData fields = new ContainerData() {
@Override
public int getCount() {
return DropperTileEntity.NUM_OF_FIELDS;
}
public void reset_rtstate()
{
block_power_signal_ = false;
block_power_updated_ = false;
Arrays.fill(filter_matches_, 0);
}
public void readnbt(CompoundTag nbt, boolean update_packet)
{
main_inventory_.load(nbt);
block_power_signal_ = nbt.getBoolean("powered");
open_timer_ = nbt.getInt("open_timer");
drop_speed_ = nbt.getInt("drop_speed");
drop_noise_ = nbt.getInt("drop_noise");
drop_xdev_ = nbt.getInt("drop_xdev");
drop_ydev_ = nbt.getInt("drop_ydev");
drop_slot_index_ = nbt.getInt("drop_slot_index");
drop_count_ = Mth.clamp(nbt.getInt("drop_count"), 1, MAX_DROP_COUNT);
drop_logic_ = nbt.getInt("drop_logic");
drop_period_ = nbt.getInt("drop_period");
}
protected void writenbt(CompoundTag nbt, boolean update_packet)
{
main_inventory_.save(nbt);
nbt.putBoolean("powered", block_power_signal_);
nbt.putInt("open_timer", open_timer_);
nbt.putInt("drop_speed", drop_speed_);
nbt.putInt("drop_noise", drop_noise_);
nbt.putInt("drop_xdev", drop_xdev_);
nbt.putInt("drop_ydev", drop_ydev_);
nbt.putInt("drop_slot_index", drop_slot_index_);
nbt.putInt("drop_count", drop_count_);
nbt.putInt("drop_logic", drop_logic_);
nbt.putInt("drop_period", drop_period_);
}
public void block_updated()
{
// RS power check, both edges
boolean powered = level.hasNeighborSignal(worldPosition);
if(block_power_signal_ != powered) block_power_updated_ = true;
block_power_signal_ = powered;
tick_timer_ = 1;
}
// BlockEntity ------------------------------------------------------------------------------
@Override
public void load(CompoundTag nbt)
{ super.load(nbt); readnbt(nbt, false); }
@Override
protected void saveAdditional(CompoundTag nbt)
{ super.saveAdditional(nbt); writenbt(nbt, false); }
@Override
public void setRemoved()
{
super.setRemoved();
item_handler_.invalidate();
}
// Namable -----------------------------------------------------------------------------------------------
@Override
public Component getName()
{ return Auxiliaries.localizable(getBlockState().getBlock().getDescriptionId()); }
@Override
public boolean hasCustomName()
{ return false; }
@Override
public Component getCustomName()
{ return getName(); }
// INamedContainerProvider ------------------------------------------------------------------------------
@Override
public Component getDisplayName()
{ return Nameable.super.getDisplayName(); }
@Override
public AbstractContainerMenu createMenu(int id, Inventory inventory, Player player )
{ return new DropperUiContainer(id, inventory, main_inventory_, ContainerLevelAccess.create(level, worldPosition), fields); }
// Fields -----------------------------------------------------------------------------------------------
protected final ContainerData fields = new ContainerData()
{
@Override
public int getCount()
{ return DropperTileEntity.NUM_OF_FIELDS; }
@Override
public int get(int id)
{
public int get(int id) {
return switch (id) {
case 0 -> drop_speed_;
case 1 -> drop_xdev_;
@ -354,9 +244,9 @@ public class EdDropper
default -> 0;
};
}
@Override
public void set(int id, int value)
{
public void set(int id, int value) {
switch (id) {
case 0 -> drop_speed_ = Mth.clamp(value, 0, 100);
case 1 -> drop_xdev_ = Mth.clamp(value, -100, 100);
@ -371,24 +261,19 @@ public class EdDropper
case 12 -> filter_matches_[0] = (value & 0x3);
case 13 -> filter_matches_[1] = (value & 0x3);
case 14 -> filter_matches_[2] = (value & 0x3);
case 15 -> drop_slot_index_ = Mth.clamp(value, INPUT_SLOTS_FIRST, INPUT_SLOTS_FIRST + INPUT_SLOTS_SIZE - 1);
case 15 ->
drop_slot_index_ = Mth.clamp(value, INPUT_SLOTS_FIRST, INPUT_SLOTS_FIRST + INPUT_SLOTS_SIZE - 1);
}
}
};
private int tick_timer_ = 0;
// Capability export ------------------------------------------------------------------------------------
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if(capability == ForgeCapabilities.ITEM_HANDLER) return item_handler_.cast();
return super.getCapability(capability, facing);
public DropperTileEntity(BlockPos pos, BlockState state) {
super(ModContent.getBlockEntityTypeOfBlock(state.getBlock()), pos, state);
reset_rtstate();
}
// ITickable and aux methods ----------------------------------------------------------------------------
private static void drop(Level world, BlockPos pos, Direction facing, ItemStack stack, int speed_percent, int xdeviation, int ydeviation, int noise_percent)
{
private static void drop(Level world, BlockPos pos, Direction facing, ItemStack stack, int speed_percent, int xdeviation, int ydeviation, int noise_percent) {
final double ofs = facing == Direction.DOWN ? 0.8 : 0.7;
Vec3 v0 = new Vec3(facing.getStepX(), facing.getStepY(), facing.getStepZ());
final ItemEntity ei = new ItemEntity(world, (pos.getX() + 0.5) + (ofs * v0.x), (pos.getY() + 0.5) + (ofs * v0.y), (pos.getZ() + 0.5) + (ofs * v0.z), stack);
@ -420,8 +305,7 @@ public class EdDropper
world.addFreshEntity(ei);
}
private static Tuple<Boolean, List<ItemStack>> try_eject(Level world, BlockPos pos, Direction facing, ItemStack[] stacks, int speed_percent, int xdeviation, int ydeviation, int noise_percent)
{
private static Tuple<Boolean, List<ItemStack>> try_eject(Level world, BlockPos pos, Direction facing, ItemStack[] stacks, int speed_percent, int xdeviation, int ydeviation, int noise_percent) {
if (Arrays.stream(stacks).allMatch(ItemStack::isEmpty)) return new Tuple<>(false, Arrays.asList(stacks));
if (with_adjacent_item_insertion) {
final BlockEntity te = world.getBlockEntity(pos.relative(facing));
@ -446,9 +330,125 @@ public class EdDropper
return new Tuple<>(true, Collections.emptyList());
}
private static int next_slot(int i) {
return (i < INPUT_SLOTS_SIZE - 1) ? (i + 1) : INPUT_SLOTS_FIRST;
}
public CompoundTag clear_getnbt() {
CompoundTag nbt = new CompoundTag();
writenbt(nbt, false);
main_inventory_.clearContent();
reset_rtstate();
triggered_ = false;
block_power_updated_ = false;
return nbt;
}
// BlockEntity ------------------------------------------------------------------------------
public void reset_rtstate() {
block_power_signal_ = false;
block_power_updated_ = false;
Arrays.fill(filter_matches_, 0);
}
public void readnbt(CompoundTag nbt, boolean update_packet) {
main_inventory_.load(nbt);
block_power_signal_ = nbt.getBoolean("powered");
open_timer_ = nbt.getInt("open_timer");
drop_speed_ = nbt.getInt("drop_speed");
drop_noise_ = nbt.getInt("drop_noise");
drop_xdev_ = nbt.getInt("drop_xdev");
drop_ydev_ = nbt.getInt("drop_ydev");
drop_slot_index_ = nbt.getInt("drop_slot_index");
drop_count_ = Mth.clamp(nbt.getInt("drop_count"), 1, MAX_DROP_COUNT);
drop_logic_ = nbt.getInt("drop_logic");
drop_period_ = nbt.getInt("drop_period");
}
protected void writenbt(CompoundTag nbt, boolean update_packet) {
main_inventory_.save(nbt);
nbt.putBoolean("powered", block_power_signal_);
nbt.putInt("open_timer", open_timer_);
nbt.putInt("drop_speed", drop_speed_);
nbt.putInt("drop_noise", drop_noise_);
nbt.putInt("drop_xdev", drop_xdev_);
nbt.putInt("drop_ydev", drop_ydev_);
nbt.putInt("drop_slot_index", drop_slot_index_);
nbt.putInt("drop_count", drop_count_);
nbt.putInt("drop_logic", drop_logic_);
nbt.putInt("drop_period", drop_period_);
}
// Namable -----------------------------------------------------------------------------------------------
public void block_updated() {
// RS power check, both edges
boolean powered = level.hasNeighborSignal(worldPosition);
if (block_power_signal_ != powered) block_power_updated_ = true;
block_power_signal_ = powered;
tick_timer_ = 1;
}
@Override
public void load(CompoundTag nbt) {
super.load(nbt);
readnbt(nbt, false);
}
@Override
protected void saveAdditional(CompoundTag nbt) {
super.saveAdditional(nbt);
writenbt(nbt, false);
}
// INamedContainerProvider ------------------------------------------------------------------------------
@Override
public void setRemoved() {
super.setRemoved();
item_handler_.invalidate();
}
@Override
public Component getName() {
return Auxiliaries.localizable(getBlockState().getBlock().getDescriptionId());
}
// Fields -----------------------------------------------------------------------------------------------
@Override
public boolean hasCustomName() {
return false;
}
// Capability export ------------------------------------------------------------------------------------
@Override
public Component getCustomName() {
return getName();
}
// ITickable and aux methods ----------------------------------------------------------------------------
@Override
public Component getDisplayName() {
return Nameable.super.getDisplayName();
}
@Override
public AbstractContainerMenu createMenu(int id, Inventory inventory, Player player) {
return new DropperUiContainer(id, inventory, main_inventory_, ContainerLevelAccess.create(level, worldPosition), fields);
}
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing) {
if (capability == ForgeCapabilities.ITEM_HANDLER) return item_handler_.cast();
return super.getCapability(capability, facing);
}
@Nullable
BlockState update_blockstate()
{
BlockState update_blockstate() {
BlockState state = level.getBlockState(worldPosition);
if (!(state.getBlock() instanceof DropperBlock)) return null;
boolean open = (open_timer_ > 0);
@ -466,12 +466,8 @@ public class EdDropper
return state;
}
private static int next_slot(int i)
{ return (i<INPUT_SLOTS_SIZE-1) ? (i+1) : INPUT_SLOTS_FIRST; }
@Override
public void tick()
{
public void tick() {
if (level.isClientSide) return;
if (--open_timer_ < 0) open_timer_ = 0;
if ((drop_timer_ > 0) && ((--drop_timer_) == 0)) setChanged();
@ -500,9 +496,15 @@ public class EdDropper
int inventory_item_count = 0;
int slot = drop_slot_index_;
for (final ItemStack inp_stack : storage_slot_range_) {
if(Inventories.areItemStacksDifferent(inp_stack, cmp_stack)) { slot = next_slot(slot); continue; }
if (Inventories.areItemStacksDifferent(inp_stack, cmp_stack)) {
slot = next_slot(slot);
continue;
}
inventory_item_count += inp_stack.getCount();
if(inventory_item_count < cmp_stack_count) { slot = next_slot(slot); continue; }
if (inventory_item_count < cmp_stack_count) {
slot = next_slot(slot);
continue;
}
filter_matches_[ci] = 2;
break;
}
@ -515,7 +517,8 @@ public class EdDropper
}
filter_defined = (filter_nset > 0);
filter_trigger = ((filter_nset > 0) && (nmatched > 0));
if(((drop_logic_ & DROPLOGIC_FILTER_ANDGATE) != 0) && (nmatched != filter_nset)) filter_trigger = false;
if (((drop_logic_ & DROPLOGIC_FILTER_ANDGATE) != 0) && (nmatched != filter_nset))
filter_trigger = false;
}
// gates
{
@ -524,7 +527,10 @@ public class EdDropper
} else {
trigger = redstone_trigger;
}
if(triggered_) { triggered_ = false; trigger = true; }
if (triggered_) {
triggered_ = false;
trigger = true;
}
if (storage_slot_range_.stream().noneMatch(is -> is.getCount() >= drop_count_)) {
if (open_timer_ > 10) open_timer_ = 10; // override if dropping is not possible at all.
} else if (trigger || filter_trigger || redstone_trigger) {
@ -541,7 +547,10 @@ public class EdDropper
}
// block state update
final BlockState state = update_blockstate();
if(state == null) { block_power_signal_= false; return; }
if (state == null) {
block_power_signal_ = false;
return;
}
// dispense action
if (trigger && (drop_timer_ <= 0)) {
// drop stack for non-filter triggers
@ -593,7 +602,8 @@ public class EdDropper
final boolean dropped = res.getA();
final List<ItemStack> remaining = res.getB();
for (ItemStack st : remaining) {
if(!storage_slot_range_.insert(st).isEmpty()) Auxiliaries.logger().debug("NOT ALL NON-DROPPED ITEMS PUT BACK:" + st);
if (!storage_slot_range_.insert(st).isEmpty())
Auxiliaries.logger().debug("NOT ALL NON-DROPPED ITEMS PUT BACK:" + st);
}
if (dropped || (!remaining.isEmpty())) dirty = true;
// cooldown
@ -607,7 +617,10 @@ public class EdDropper
{
boolean found = false;
for (int i = 0; i < storage_slot_range_.size(); ++i) {
if(!main_inventory_.getItem(drop_slot_index_).isEmpty()) { found=true; break; }
if (!main_inventory_.getItem(drop_slot_index_).isEmpty()) {
found = true;
break;
}
drop_slot_index_ = next_slot(drop_slot_index_);
}
if (!found) drop_slot_index_ = 0;
@ -622,31 +635,28 @@ public class EdDropper
// Container
//--------------------------------------------------------------------------------------------------------------------
public static class DropperUiContainer extends AbstractContainerMenu implements Networking.INetworkSynchronisableContainer
{
public static class DropperUiContainer extends AbstractContainerMenu implements Networking.INetworkSynchronisableContainer {
protected static final String QUICK_MOVE_ALL = "quick-move-all";
private static final int PLAYER_INV_START_SLOTNO = DropperTileEntity.NUM_OF_SLOTS;
private final Player player_;
private final Container inventory_;
private final ContainerLevelAccess wpc_;
private final ContainerData fields_;
private final InventoryRange player_inventory_range_;
private final InventoryRange block_storage_range_;
private final Inventories.InventoryRange player_inventory_range_;
private final Inventories.InventoryRange block_storage_range_;
public final int field(int index) { return fields_.get(index); }
public DropperUiContainer(int cid, Inventory player_inventory) {
this(cid, player_inventory, new SimpleContainer(DropperTileEntity.NUM_OF_SLOTS), ContainerLevelAccess.NULL, new SimpleContainerData(DropperTileEntity.NUM_OF_FIELDS));
}
public DropperUiContainer(int cid, Inventory player_inventory)
{ this(cid, player_inventory, new SimpleContainer(DropperTileEntity.NUM_OF_SLOTS), ContainerLevelAccess.NULL, new SimpleContainerData(DropperTileEntity.NUM_OF_FIELDS)); }
private DropperUiContainer(int cid, Inventory player_inventory, Container block_inventory, ContainerLevelAccess wpc, ContainerData fields)
{
private DropperUiContainer(int cid, Inventory player_inventory, Container block_inventory, ContainerLevelAccess wpc, ContainerData fields) {
super(ModContent.getMenuType("factory_dropper"), cid); // @todo: class mapping
fields_ = fields;
wpc_ = wpc;
player_ = player_inventory.player;
inventory_ = block_inventory;
block_storage_range_ = new InventoryRange(inventory_, 0, DropperTileEntity.NUM_OF_SLOTS);
player_inventory_range_ = InventoryRange.fromPlayerInventory(player_);
block_storage_range_ = new Inventories.InventoryRange(inventory_, 0, DropperTileEntity.NUM_OF_SLOTS);
player_inventory_range_ = Inventories.InventoryRange.fromPlayerInventory(player_);
int i = -1;
// input slots (stacks 0 to 11)
for (int y = 0; y < 2; ++y) {
@ -671,20 +681,25 @@ public class EdDropper
this.addDataSlots(fields_); // === Add reference holders
}
@Override
public boolean stillValid(Player player)
{ return inventory_.stillValid(player); }
public final int field(int index) {
return fields_.get(index);
}
@Override
public ItemStack quickMoveStack(Player player, int index)
{
public boolean stillValid(Player player) {
return inventory_.stillValid(player);
}
@Override
public ItemStack quickMoveStack(Player player, int index) {
Slot slot = getSlot(index);
if ((slot == null) || (!slot.hasItem())) return ItemStack.EMPTY;
ItemStack slot_stack = slot.getItem();
ItemStack transferred = slot_stack.copy();
if ((index >= 0) && (index < PLAYER_INV_START_SLOTNO)) {
// Device slots
if(!moveItemStackTo(slot_stack, PLAYER_INV_START_SLOTNO, PLAYER_INV_START_SLOTNO+36, false)) return ItemStack.EMPTY;
if (!moveItemStackTo(slot_stack, PLAYER_INV_START_SLOTNO, PLAYER_INV_START_SLOTNO + 36, false))
return ItemStack.EMPTY;
} else if ((index >= PLAYER_INV_START_SLOTNO) && (index <= PLAYER_INV_START_SLOTNO + 36)) {
// Player slot
if (!moveItemStackTo(slot_stack, 0, DropperTileEntity.INPUT_SLOTS_SIZE, false)) return ItemStack.EMPTY;
@ -705,33 +720,32 @@ public class EdDropper
// INetworkSynchronisableContainer ---------------------------------------------------------
@OnlyIn(Dist.CLIENT)
public void onGuiAction(CompoundTag nbt)
{ Networking.PacketContainerSyncClientToServer.sendToServer(containerId, nbt); }
public void onGuiAction(CompoundTag nbt) {
Networking.PacketContainerSyncClientToServer.sendToServer(containerId, nbt);
}
@OnlyIn(Dist.CLIENT)
public void onGuiAction(String key, int value)
{
public void onGuiAction(String key, int value) {
CompoundTag nbt = new CompoundTag();
nbt.putInt(key, value);
Networking.PacketContainerSyncClientToServer.sendToServer(containerId, nbt);
}
@OnlyIn(Dist.CLIENT)
public void onGuiAction(String message, CompoundTag nbt)
{
public void onGuiAction(String message, CompoundTag nbt) {
nbt.putString("action", message);
Networking.PacketContainerSyncClientToServer.sendToServer(containerId, nbt);
}
@Override
public void onServerPacketReceived(int windowId, CompoundTag nbt)
{}
public void onServerPacketReceived(int windowId, CompoundTag nbt) {
}
@Override
public void onClientPacketReceived(int windowId, Player player, CompoundTag nbt)
{
public void onClientPacketReceived(int windowId, Player player, CompoundTag nbt) {
if (!(inventory_ instanceof Inventories.StorageInventory)) return;
if(!(((Inventories.StorageInventory)inventory_).getBlockEntity() instanceof final DropperTileEntity te)) return;
if (!(((Inventories.StorageInventory) inventory_).getBlockEntity() instanceof final DropperTileEntity te))
return;
if (nbt.contains("action")) {
boolean changed = false;
final int slotId = nbt.contains("slot") ? nbt.getInt("slot") : -1;
@ -753,11 +767,19 @@ public class EdDropper
if (nbt.contains("drop_speed")) te.drop_speed_ = Mth.clamp(nbt.getInt("drop_speed"), 0, 100);
if (nbt.contains("drop_xdev")) te.drop_xdev_ = Mth.clamp(nbt.getInt("drop_xdev"), -100, 100);
if (nbt.contains("drop_ydev")) te.drop_ydev_ = Mth.clamp(nbt.getInt("drop_ydev"), -100, 100);
if(nbt.contains("drop_count")) te.drop_count_ = Mth.clamp(nbt.getInt("drop_count"), 1, DropperTileEntity.MAX_DROP_COUNT);
if (nbt.contains("drop_count"))
te.drop_count_ = Mth.clamp(nbt.getInt("drop_count"), 1, DropperTileEntity.MAX_DROP_COUNT);
if (nbt.contains("drop_period")) te.drop_period_ = Mth.clamp(nbt.getInt("drop_period"), 0, 100);
if (nbt.contains("drop_logic")) te.drop_logic_ = nbt.getInt("drop_logic");
if(nbt.contains("manual_rstrigger") && (nbt.getInt("manual_rstrigger")!=0)) { te.block_power_signal_=true; te.block_power_updated_=true; te.tick_timer_=1; }
if(nbt.contains("manual_trigger") && (nbt.getInt("manual_trigger")!=0)) { te.tick_timer_ = 1; te.triggered_ = true; }
if (nbt.contains("manual_rstrigger") && (nbt.getInt("manual_rstrigger") != 0)) {
te.block_power_signal_ = true;
te.block_power_updated_ = true;
te.tick_timer_ = 1;
}
if (nbt.contains("manual_trigger") && (nbt.getInt("manual_trigger") != 0)) {
te.tick_timer_ = 1;
te.triggered_ = true;
}
te.setChanged();
}
}
@ -769,14 +791,13 @@ public class EdDropper
//--------------------------------------------------------------------------------------------------------------------
@OnlyIn(Dist.CLIENT)
public static class DropperGui extends Guis.ContainerGui<DropperUiContainer>
{
public DropperGui(DropperUiContainer container, Inventory player_inventory, Component title)
{ super(container, player_inventory, title, "textures/gui/factory_dropper_gui.png"); }
public static class DropperGui extends Guis.ContainerGui<DropperUiContainer> {
public DropperGui(DropperUiContainer container, Inventory player_inventory, Component title) {
super(container, player_inventory, title, "textures/gui/factory_dropper_gui.png");
}
@Override
public void init()
{
public void init() {
super.init();
{
final Block block = ModContent.getBlock(Auxiliaries.getResourceLocation(getMenu().getType()).getPath().replaceAll("^ct_", ""));
@ -796,8 +817,7 @@ public class EdDropper
}
@Override
protected void renderBgWidgets(PoseStack mx, float partialTicks, int mouseX, int mouseY)
{
protected void renderBgWidgets(GuiGraphics mx, float partialTicks, int mouseX, int mouseY) {
final int x0 = getGuiLeft(), y0 = getGuiTop(), w = getXSize(), h = getYSize();
DropperUiContainer container = getMenu();
// active drop slot
@ -806,14 +826,14 @@ public class EdDropper
if ((drop_slot_index < 0) || (drop_slot_index >= 16)) drop_slot_index = 0;
int x = (x0 + 9 + ((drop_slot_index % 6) * 18));
int y = (y0 + 5 + ((drop_slot_index / 6) * 17));
blit(mx, x, y, 180, 45, 18, 18);
mx.blit(getBackgroundImage(), x, y, 180, 45, 18, 18);
}
// filter LEDs
{
for (int i = 0; i < 3; ++i) {
int xt = 180 + (6 * container.field(12 + i)), yt = 38;
int x = x0 + 31 + (i * 36), y = y0 + 65;
blit(mx, x, y, xt, yt, 6, 6);
mx.blit(getBackgroundImage(), x, y, xt, yt, 6, 6);
}
}
// force adjustment
@ -821,31 +841,31 @@ public class EdDropper
int hy = 2 + (((100 - container.field(0)) * 21) / 100);
int x = x0 + 135, y = y0 + 12, xt = 181;
int yt = 4 + (23 - hy);
blit(mx, x, y, xt, yt, 3, hy);
mx.blit(getBackgroundImage(), x, y, xt, yt, 3, hy);
}
// angle adjustment
{
int x = x0 + 157 - 3 + ((container.field(1) * 12) / 100);
int y = y0 + 22 - 3 - ((container.field(2) * 12) / 100);
blit(mx, x, y, 180, 30, 7, 7);
mx.blit(getBackgroundImage(), x, y, 180, 30, 7, 7);
}
// drop count
{
int x = x0 + 134 - 2 + (container.field(4));
int y = y0 + 45;
blit(mx, x, y, 190, 31, 5, 5);
mx.blit(getBackgroundImage(), x, y, 190, 31, 5, 5);
}
// drop period
{
int px = (int) Math.round(((33.0 * container.field(6)) / 100) + 1);
int x = x0 + 134 - 2 + Mth.clamp(px, 0, 33);
int y = y0 + 56;
blit(mx, x, y, 190, 31, 5, 5);
mx.blit(getBackgroundImage(), x, y, 190, 31, 5, 5);
}
// redstone input
{
if (container.field(11) != 0) {
blit(mx, x0+114, y0+51, 189, 18, 9, 9);
mx.blit(getBackgroundImage(), x0 + 114, y0 + 51, 189, 18, 9, 9);
}
}
// trigger logic
@ -855,21 +875,20 @@ public class EdDropper
int pulse_mode_offset = ((logic & DropperTileEntity.DROPLOGIC_CONTINUOUS) != 0) ? 10 : 0;
int extern_gate_offset_x = ((logic & DropperTileEntity.DROPLOGIC_EXTERN_ANDGATE) != 0) ? 11 : 0;
int extern_gate_offset_y = ((logic & DropperTileEntity.DROPLOGIC_IGNORE_EXT) != 0) ? 10 : 0;
blit(mx, x0+132, y0+66, 179+filter_gate_offset, 66, 9, 9);
blit(mx, x0+148, y0+66, 179+extern_gate_offset_x, 66+extern_gate_offset_y, 9, 9);
blit(mx, x0+162, y0+66, 200+pulse_mode_offset, 66, 9, 9);
mx.blit(getBackgroundImage(), x0 + 132, y0 + 66, 179 + filter_gate_offset, 66, 9, 9);
mx.blit(getBackgroundImage(), x0 + 148, y0 + 66, 179 + extern_gate_offset_x, 66 + extern_gate_offset_y, 9, 9);
mx.blit(getBackgroundImage(), x0 + 162, y0 + 66, 200 + pulse_mode_offset, 66, 9, 9);
}
// drop timer running indicator
{
if ((container.field(9) > DropperTileEntity.DROP_PERIOD_OFFSET) && ((System.currentTimeMillis() % 1000) < 500)) {
blit(mx, x0+149, y0+51, 201, 39, 3, 3);
mx.blit(getBackgroundImage(), x0 + 149, y0 + 51, 201, 39, 3, 3);
}
}
}
@Override
public boolean mouseClicked(double mouseX, double mouseY, int mouseButton)
{
public boolean mouseClicked(double mouseX, double mouseY, int mouseButton) {
tooltip_.resetTimer();
DropperUiContainer container = getMenu();
int mx = (int) (mouseX - getGuiLeft() + .5), my = (int) (mouseY - getGuiTop() + .5);
@ -928,8 +947,7 @@ public class EdDropper
}
@Override
protected void slotClicked(Slot slot, int slotId, int button, ClickType type)
{
protected void slotClicked(Slot slot, int slotId, int button, ClickType type) {
tooltip_.resetTimer();
if ((type == ClickType.QUICK_MOVE) && (slot != null) && slot.hasItem() && Auxiliaries.isShiftDown() && Auxiliaries.isCtrlDown()) {
CompoundTag nbt = new CompoundTag();

View file

@ -8,23 +8,25 @@
*/
package dev.zontreck.engineerdecor.blocks;
import dev.zontreck.libzontreck.edlibmc.StandardFenceBlock;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState;
import dev.zontreck.engineerdecor.libmc.StandardFenceBlock;
public class EdFenceBlock extends StandardFenceBlock
{
public EdFenceBlock(long config, BlockBehaviour.Properties properties)
{ super(config, properties); }
public class EdFenceBlock extends StandardFenceBlock {
public EdFenceBlock(long config, BlockBehaviour.Properties properties) {
super(config, properties);
}
public EdFenceBlock(long config, BlockBehaviour.Properties properties, double pole_width, double pole_height, double side_width, double side_min_y, double side_max_low_y, double side_max_tall_y)
{ super(config, properties, pole_width, pole_height, side_width, side_min_y, side_max_low_y, side_max_tall_y); }
public EdFenceBlock(long config, BlockBehaviour.Properties properties, double pole_width, double pole_height, double side_width, double side_min_y, double side_max_low_y, double side_max_tall_y) {
super(config, properties, pole_width, pole_height, side_width, side_min_y, side_max_low_y, side_max_tall_y);
}
@Override
protected boolean attachesTo(BlockState facingState, LevelReader world, BlockPos facingPos, Direction side)
{ return ((facingState.getBlock()) instanceof EdDoubleGateBlock) || super.attachesTo(facingState, world, facingPos, side); }
protected boolean attachesTo(BlockState facingState, LevelReader world, BlockPos facingPos, Direction side) {
return ((facingState.getBlock()) instanceof EdDoubleGateBlock) || super.attachesTo(facingState, world, facingPos, side);
}
}

View file

@ -8,6 +8,7 @@
*/
package dev.zontreck.engineerdecor.blocks;
import dev.zontreck.libzontreck.edlibmc.StandardBlocks;
import net.minecraft.core.BlockPos;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
@ -19,32 +20,33 @@ import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import dev.zontreck.engineerdecor.libmc.StandardBlocks;
import javax.annotation.Nullable;
public class EdFloorGratingBlock extends StandardBlocks.WaterLoggable
{
public EdFloorGratingBlock(long config, BlockBehaviour.Properties builder, final AABB unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
public class EdFloorGratingBlock extends StandardBlocks.WaterLoggable {
public EdFloorGratingBlock(long config, BlockBehaviour.Properties builder, final AABB unrotatedAABB) {
super(config, builder, unrotatedAABB);
}
@Override
public RenderTypeHint getRenderTypeHint()
{ return RenderTypeHint.CUTOUT; }
public RenderTypeHint getRenderTypeHint() {
return RenderTypeHint.CUTOUT;
}
@Override
public boolean propagatesSkylightDown(BlockState state, BlockGetter reader, BlockPos pos)
{ return true; }
public boolean propagatesSkylightDown(BlockState state, BlockGetter reader, BlockPos pos) {
return true;
}
@Override
public boolean isValidSpawn(BlockState state, BlockGetter world, BlockPos pos, SpawnPlacements.Type type, @Nullable EntityType<?> entityType)
{ return false; }
public boolean isValidSpawn(BlockState state, BlockGetter world, BlockPos pos, SpawnPlacements.Type type, @Nullable EntityType<?> entityType) {
return false;
}
@Override
@SuppressWarnings("deprecation")
public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity)
{
public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
if (!(entity instanceof ItemEntity)) return;
final boolean colliding = ((entity.position().y - pos.getY()) > 0.7);
if (colliding || (entity.getDeltaMovement().y() > 0)) {

View file

@ -8,6 +8,9 @@
*/
package dev.zontreck.engineerdecor.blocks;
import dev.zontreck.engineerdecor.ModConfig;
import dev.zontreck.engineerdecor.ModContent;
import dev.zontreck.libzontreck.edlibmc.*;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
@ -29,7 +32,7 @@ import net.minecraft.world.item.TooltipFlag;
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.SignalGetter;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockBehaviour;
@ -50,21 +53,13 @@ import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.IFluidHandler;
import dev.zontreck.engineerdecor.ModConfig;
import dev.zontreck.engineerdecor.ModContent;
import dev.zontreck.engineerdecor.libmc.StandardBlocks;
import dev.zontreck.engineerdecor.libmc.StandardEntityBlocks;
import dev.zontreck.engineerdecor.libmc.Auxiliaries;
import dev.zontreck.engineerdecor.libmc.Fluidics;
import dev.zontreck.engineerdecor.libmc.Overlay;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
public class EdFluidBarrel
{
public class EdFluidBarrel {
//--------------------------------------------------------------------------------------------------------------------
// Config
//--------------------------------------------------------------------------------------------------------------------
@ -73,8 +68,7 @@ public class EdFluidBarrel
private static int item_fluid_handler_transfer_rate_ = 1000;
private static int tile_fluid_handler_transfer_rate_ = 1000;
public static void on_config(int tank_capacity, int transfer_rate)
{
public static void on_config(int tank_capacity, int transfer_rate) {
capacity_ = Mth.clamp(tank_capacity, 2000, 64000);
tile_fluid_handler_transfer_rate_ = Mth.clamp(tank_capacity, 50, 4096);
item_fluid_handler_transfer_rate_ = tile_fluid_handler_transfer_rate_;
@ -85,28 +79,27 @@ public class EdFluidBarrel
// Block
//--------------------------------------------------------------------------------------------------------------------
public static class FluidBarrelBlock extends StandardBlocks.DirectedWaterLoggable implements StandardEntityBlocks.IStandardEntityBlock<FluidBarrelTileEntity>
{
public static class FluidBarrelBlock extends StandardBlocks.DirectedWaterLoggable implements StandardEntityBlocks.IStandardEntityBlock<FluidBarrelTileEntity> {
public static final int FILL_LEVEL_MAX = 4;
public static final IntegerProperty FILL_LEVEL = IntegerProperty.create("level", 0, FILL_LEVEL_MAX);
public FluidBarrelBlock(long config, BlockBehaviour.Properties builder, final AABB[] unrotatedAABB)
{
public FluidBarrelBlock(long config, BlockBehaviour.Properties builder, final AABB[] unrotatedAABB) {
super(config, builder, unrotatedAABB);
registerDefaultState(super.defaultBlockState().setValue(FACING, Direction.UP).setValue(FILL_LEVEL, 0));
}
@Override
public boolean isBlockEntityTicking(Level world, BlockState state)
{ return true; }
public boolean isBlockEntityTicking(Level world, BlockState state) {
return true;
}
@Override
public boolean hasDynamicDropList()
{ return true; }
public boolean hasDynamicDropList() {
return true;
}
@Override
public List<ItemStack> dropList(BlockState state, Level world, final BlockEntity te, boolean explosion)
{
public List<ItemStack> dropList(BlockState state, Level world, final BlockEntity te, boolean explosion) {
final List<ItemStack> stacks = new ArrayList<>();
if (world.isClientSide) return stacks;
if (!(te instanceof FluidBarrelTileEntity)) return stacks;
@ -123,10 +116,10 @@ public class EdFluidBarrel
@Override
@OnlyIn(Dist.CLIENT)
public void appendHoverText(final ItemStack stack, @Nullable BlockGetter world, List<Component> tooltip, TooltipFlag flag)
{
public void appendHoverText(final ItemStack stack, @Nullable BlockGetter world, List<Component> tooltip, TooltipFlag flag) {
if ((!(stack.getItem() instanceof FluidBarrelItem)) || (Auxiliaries.Tooltip.helpCondition())) {
super.appendHoverText(stack, world, tooltip, flag); return;
super.appendHoverText(stack, world, tooltip, flag);
return;
}
FluidStack fs = FluidBarrelItem.getFluid(stack);
if (!fs.isEmpty()) {
@ -140,25 +133,26 @@ public class EdFluidBarrel
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext)
{ return Shapes.block(); }
public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) {
return Shapes.block();
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder)
{ super.createBlockStateDefinition(builder); builder.add(FILL_LEVEL); }
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
super.createBlockStateDefinition(builder);
builder.add(FILL_LEVEL);
}
@Override
@Nullable
public BlockState getStateForPlacement(BlockPlaceContext context)
{
public BlockState getStateForPlacement(BlockPlaceContext context) {
BlockState state = super.getStateForPlacement(context);
if (!context.getPlayer().isShiftKeyDown()) state = state.setValue(FACING, Direction.UP);
return state;
}
@Override
public void setPlacedBy(Level world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack)
{
public void setPlacedBy(Level world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) {
if (world.isClientSide) return;
if ((!stack.hasTag()) || (!stack.getTag().contains("tedata"))) return;
CompoundTag te_nbt = stack.getTag().getCompound("tedata");
@ -172,9 +166,9 @@ public class EdFluidBarrel
@Override
@SuppressWarnings("deprecation")
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult rayTraceResult)
{
if(player.getItemInHand(hand).getItem() == asItem()) return InteractionResult.PASS; // Pass that to block placement.
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult rayTraceResult) {
if (player.getItemInHand(hand).getItem() == asItem())
return InteractionResult.PASS; // Pass that to block placement.
if (world.isClientSide()) return InteractionResult.SUCCESS;
if (!(world.getBlockEntity(pos) instanceof final FluidBarrelTileEntity te)) return InteractionResult.FAIL;
if (!te.handlePlayerInteraction(state, world, pos, player, hand)) return InteractionResult.PASS;
@ -184,21 +178,22 @@ public class EdFluidBarrel
@Override
@SuppressWarnings("deprecation")
public boolean hasAnalogOutputSignal(BlockState state)
{ return true; }
public boolean hasAnalogOutputSignal(BlockState state) {
return true;
}
@Override
@SuppressWarnings("deprecation")
public int getAnalogOutputSignal(BlockState state, Level world, BlockPos pos)
{
public int getAnalogOutputSignal(BlockState state, Level world, BlockPos pos) {
BlockEntity te = world.getBlockEntity(pos);
if (!(te instanceof FluidBarrelTileEntity)) return 0;
return (int) Mth.clamp(((FluidBarrelTileEntity) te).getNormalizedFillLevel() * 15, 0, 15);
}
@Override
public boolean shouldCheckWeakPower(BlockState state, LevelReader world, BlockPos pos, Direction side)
{ return false; }
public boolean shouldCheckWeakPower(BlockState state, SignalGetter level, BlockPos pos, Direction side) {
return false;
}
}
@ -206,24 +201,26 @@ public class EdFluidBarrel
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
public static class FluidBarrelTileEntity extends StandardEntityBlocks.StandardBlockEntity implements ICapabilityProvider
{
public static class FluidBarrelTileEntity extends StandardEntityBlocks.StandardBlockEntity implements ICapabilityProvider {
private final int TICK_INTERVAL = 10;
private int tick_timer_ = 0;
private final Fluidics.Tank tank_ = (new Fluidics.Tank(capacity_)).setInteractionNotifier((t, d) -> on_tank_changed());
private final LazyOptional<IFluidHandler> fluid_handler_ = tank_.createFluidHandler();
public FluidBarrelTileEntity(BlockPos pos, BlockState state)
{ super(ModContent.getBlockEntityTypeOfBlock(state.getBlock()), pos, state); }
public FluidBarrelTileEntity(BlockPos pos, BlockState state) {
super(ModContent.getBlockEntityTypeOfBlock(state.getBlock()), pos, state);
}
public void readnbt(CompoundTag nbt)
{ tank_.load(nbt); }
public void readnbt(CompoundTag nbt) {
tank_.load(nbt);
}
public CompoundTag writenbt(CompoundTag nbt)
{ tank_.save(nbt); return nbt; }
public CompoundTag writenbt(CompoundTag nbt) {
tank_.save(nbt);
return nbt;
}
public boolean handlePlayerInteraction(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand)
{
public boolean handlePlayerInteraction(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand) {
if (world.isClientSide()) return false;
{
Tuple<Fluid, Integer> transferred = Fluidics.manualTrackedFluidHandlerInteraction(world, pos, null, player, hand);
@ -250,42 +247,49 @@ public class EdFluidBarrel
return true;
}
public double getNormalizedFillLevel()
{ return (tank_.isEmpty()) ? (0) : ((double)tank_.getFluidAmount()/(double)tank_.getCapacity()); }
public double getNormalizedFillLevel() {
return (tank_.isEmpty()) ? (0) : ((double) tank_.getFluidAmount() / (double) tank_.getCapacity());
}
protected void on_tank_changed()
{ if(tick_timer_ > 2) tick_timer_ = 2; }
protected void on_tank_changed() {
if (tick_timer_ > 2) tick_timer_ = 2;
}
// BlockEntity ------------------------------------------------------------------------------
@Override
public void load(CompoundTag nbt)
{ super.load(nbt); readnbt(nbt); }
public void load(CompoundTag nbt) {
super.load(nbt);
readnbt(nbt);
}
@Override
protected void saveAdditional(CompoundTag nbt)
{ super.saveAdditional(nbt); writenbt(nbt); }
protected void saveAdditional(CompoundTag nbt) {
super.saveAdditional(nbt);
writenbt(nbt);
}
@Override
public void setRemoved()
{ super.setRemoved(); fluid_handler_.invalidate(); }
public void setRemoved() {
super.setRemoved();
fluid_handler_.invalidate();
}
public CompoundTag clear_getnbt()
{ return tank_.save(new CompoundTag()); }
public CompoundTag clear_getnbt() {
return tank_.save(new CompoundTag());
}
// ICapabilityProvider --------------------------------------------------------------------
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing) {
if (capability == ForgeCapabilities.FLUID_HANDLER) return fluid_handler_.cast();
return super.getCapability(capability, facing);
}
// Tick --------------------------------------------------------------------
private boolean transfer_down()
{
private boolean transfer_down() {
if (tank_.isEmpty()) return false;
final IFluidHandler fh = Fluidics.handler(level, worldPosition.below(), Direction.UP);
if (fh == null) return false;
@ -297,14 +301,14 @@ public class EdFluidBarrel
return true;
}
public void tick()
{
public void tick() {
if ((level.isClientSide()) || (--tick_timer_ >= 0)) return;
tick_timer_ = TICK_INTERVAL;
final BlockState state = getBlockState();
final Block block = state.getBlock();
if (!(block instanceof FluidBarrelBlock)) return;
if(state.getValue(FluidBarrelBlock.FACING).getAxis().isVertical()) transfer_down(); // tick_timer_ ==> 1 if something was transferred, otherwise no need to waste CPU
if (state.getValue(FluidBarrelBlock.FACING).getAxis().isVertical())
transfer_down(); // tick_timer_ ==> 1 if something was transferred, otherwise no need to waste CPU
double norm_level = getNormalizedFillLevel();
int fill_level = (norm_level <= 0) ? 0 : ((int) Mth.clamp((norm_level * FluidBarrelBlock.FILL_LEVEL_MAX) + 0.5, 1, FluidBarrelBlock.FILL_LEVEL_MAX));
if (fill_level != state.getValue(FluidBarrelBlock.FILL_LEVEL)) {
@ -319,21 +323,19 @@ public class EdFluidBarrel
// Block item
//--------------------------------------------------------------------------------------------------------------------
public static class FluidBarrelItem extends BlockItem
{
public FluidBarrelItem(Block block, Item.Properties builder)
{ super(block, builder); }
public static class FluidBarrelItem extends BlockItem {
public FluidBarrelItem(Block block, Item.Properties builder) {
super(block, builder);
}
private static CompoundTag read_fluid_nbt(ItemStack stack)
{
private static CompoundTag read_fluid_nbt(ItemStack stack) {
if ((!stack.hasTag()) || (!stack.getTag().contains("tedata"))) return new CompoundTag();
final CompoundTag nbt = stack.getTag().getCompound("tedata");
if (!nbt.contains("tank", Tag.TAG_COMPOUND)) return new CompoundTag();
return nbt.getCompound("tank");
}
private static void write_fluid_nbt(ItemStack stack, CompoundTag fluid_nbt)
{
private static void write_fluid_nbt(ItemStack stack, CompoundTag fluid_nbt) {
if ((fluid_nbt == null) || (fluid_nbt.isEmpty())) {
if ((!stack.hasTag()) || (!stack.getTag().contains("tedata", Tag.TAG_COMPOUND))) return;
final CompoundTag tag = stack.getTag();
@ -352,45 +354,52 @@ public class EdFluidBarrel
}
}
public static FluidStack getFluid(ItemStack stack)
{
public static FluidStack getFluid(ItemStack stack) {
final CompoundTag nbt = read_fluid_nbt(stack);
return (nbt.isEmpty()) ? (FluidStack.EMPTY) : (FluidStack.loadFluidStackFromNBT(nbt));
}
public static ItemStack setFluid(ItemStack stack, FluidStack fs)
{ write_fluid_nbt(stack, fs.writeToNBT(new CompoundTag())); return stack; }
public static ItemStack setFluid(ItemStack stack, FluidStack fs) {
write_fluid_nbt(stack, fs.writeToNBT(new CompoundTag()));
return stack;
}
@Override
public int getMaxStackSize(ItemStack stack)
{ return (!getFluid(stack).isEmpty()) ? 1 : super.getMaxStackSize(stack); }
public int getMaxStackSize(ItemStack stack) {
return (!getFluid(stack).isEmpty()) ? 1 : super.getMaxStackSize(stack);
}
@Override
public boolean isBarVisible(ItemStack stack)
{ return (!getFluid(stack).isEmpty()); }
public boolean isBarVisible(ItemStack stack) {
return (!getFluid(stack).isEmpty());
}
@Override
public int getBarWidth(ItemStack stack)
{ return (int)Math.round(13f * Mth.clamp(((double)(getFluid(stack).getAmount()))/((double)capacity_), 0.0, 1.0)); }
public int getBarWidth(ItemStack stack) {
return (int) Math.round(13f * Mth.clamp(((double) (getFluid(stack).getAmount())) / ((double) capacity_), 0.0, 1.0));
}
@Override
public int getBarColor(ItemStack stack)
{ return 0x336633; }
public int getBarColor(ItemStack stack) {
return 0x336633;
}
@Override
public ICapabilityProvider initCapabilities(ItemStack stack, @Nullable CompoundTag nbt)
{ return new Fluidics.FluidContainerItemCapabilityWrapper(stack, capacity_, item_fluid_handler_transfer_rate_, FluidBarrelItem::read_fluid_nbt, FluidBarrelItem::write_fluid_nbt, e->true); }
public ICapabilityProvider initCapabilities(ItemStack stack, @Nullable CompoundTag nbt) {
return new Fluidics.FluidContainerItemCapabilityWrapper(stack, capacity_, item_fluid_handler_transfer_rate_, FluidBarrelItem::read_fluid_nbt, FluidBarrelItem::write_fluid_nbt, e -> true);
}
@Override
public boolean hasCraftingRemainingItem(ItemStack stack)
{ return (stack.getCount()==1) && (!getFluid(stack).isEmpty()); }
public boolean hasCraftingRemainingItem(ItemStack stack) {
return (stack.getCount() == 1) && (!getFluid(stack).isEmpty());
}
@Override
public ItemStack getCraftingRemainingItem(ItemStack stack)
{
public ItemStack getCraftingRemainingItem(ItemStack stack) {
if (stack.getCount() != 1) return ItemStack.EMPTY;
FluidStack fs = getFluid(stack);
if(fs.getAmount() > 1000) fs.shrink(1000); else fs = FluidStack.EMPTY;
if (fs.getAmount() > 1000) fs.shrink(1000);
else fs = FluidStack.EMPTY;
return setFluid(stack, fs);
}
}

View file

@ -10,6 +10,11 @@
*/
package dev.zontreck.engineerdecor.blocks;
import dev.zontreck.engineerdecor.ModConfig;
import dev.zontreck.engineerdecor.ModContent;
import dev.zontreck.libzontreck.edlibmc.Fluidics;
import dev.zontreck.libzontreck.edlibmc.StandardBlocks;
import dev.zontreck.libzontreck.edlibmc.StandardEntityBlocks;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Vec3i;
@ -23,7 +28,7 @@ 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.SignalGetter;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BlockEntity;
@ -43,23 +48,16 @@ import net.minecraftforge.common.capabilities.ForgeCapabilities;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.IFluidHandler;
import dev.zontreck.engineerdecor.ModConfig;
import dev.zontreck.engineerdecor.ModContent;
import dev.zontreck.engineerdecor.libmc.StandardBlocks;
import dev.zontreck.engineerdecor.libmc.StandardEntityBlocks;
import dev.zontreck.engineerdecor.libmc.Fluidics;
import javax.annotation.Nullable;
import java.util.*;
public class EdFluidFunnel
{
public class EdFluidFunnel {
private static boolean with_device_fluid_handler_collection = false;
public static void on_config(boolean with_tank_fluid_collection)
{
public static void on_config(boolean with_tank_fluid_collection) {
with_device_fluid_handler_collection = with_tank_fluid_collection;
ModConfig.log("Config fluid funnel: tank-fluid-collection:" + with_device_fluid_handler_collection + ".");
}
@ -68,48 +66,55 @@ public class EdFluidFunnel
// Block
//--------------------------------------------------------------------------------------------------------------------
public static class FluidFunnelBlock extends StandardBlocks.Cutout implements StandardEntityBlocks.IStandardEntityBlock<FluidFunnelTileEntity>
{
public static class FluidFunnelBlock extends StandardBlocks.Cutout implements StandardEntityBlocks.IStandardEntityBlock<FluidFunnelTileEntity> {
public static final int FILL_LEVEL_MAX = 3;
public static final IntegerProperty FILL_LEVEL = IntegerProperty.create("level", 0, FILL_LEVEL_MAX);
public FluidFunnelBlock(long config, BlockBehaviour.Properties builder, final AABB[] unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
public FluidFunnelBlock(long config, BlockBehaviour.Properties builder, final AABB[] unrotatedAABB) {
super(config, builder, unrotatedAABB);
}
@Override
public boolean isBlockEntityTicking(Level world, BlockState state)
{ return true; }
public boolean isBlockEntityTicking(Level world, BlockState state) {
return true;
}
@Override
public RenderTypeHint getRenderTypeHint()
{ return RenderTypeHint.CUTOUT; }
public RenderTypeHint getRenderTypeHint() {
return RenderTypeHint.CUTOUT;
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext)
{ return Shapes.block(); }
public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) {
return Shapes.block();
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder)
{ super.createBlockStateDefinition(builder); builder.add(FILL_LEVEL); }
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
super.createBlockStateDefinition(builder);
builder.add(FILL_LEVEL);
}
@Override
@Nullable
public BlockState getStateForPlacement(BlockPlaceContext context)
{ return super.getStateForPlacement(context).setValue(FILL_LEVEL, 0); }
public BlockState getStateForPlacement(BlockPlaceContext context) {
return super.getStateForPlacement(context).setValue(FILL_LEVEL, 0);
}
@Override
@SuppressWarnings("deprecation")
public boolean hasAnalogOutputSignal(BlockState state)
{ return true; }
public boolean hasAnalogOutputSignal(BlockState state) {
return true;
}
@Override
@SuppressWarnings("deprecation")
public int getAnalogOutputSignal(BlockState state, Level world, BlockPos pos)
{ return Mth.clamp((state.getValue(FILL_LEVEL)*5), 0, 15); }
public int getAnalogOutputSignal(BlockState state, Level world, BlockPos pos) {
return Mth.clamp((state.getValue(FILL_LEVEL) * 5), 0, 15);
}
@Override
public void setPlacedBy(Level world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack)
{
public void setPlacedBy(Level world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) {
if (world.isClientSide) return;
if ((!stack.hasTag()) || (!stack.getTag().contains("tedata"))) return;
CompoundTag te_nbt = stack.getTag().getCompound("tedata");
@ -122,12 +127,12 @@ public class EdFluidFunnel
}
@Override
public boolean hasDynamicDropList()
{ return true; }
public boolean hasDynamicDropList() {
return true;
}
@Override
public List<ItemStack> dropList(BlockState state, Level world, final BlockEntity te, boolean explosion)
{
public List<ItemStack> dropList(BlockState state, Level world, final BlockEntity te, boolean explosion) {
final List<ItemStack> stacks = new ArrayList<>();
if (world.isClientSide) return stacks;
if (!(te instanceof FluidFunnelTileEntity)) return stacks;
@ -149,28 +154,30 @@ public class EdFluidFunnel
@Override
@SuppressWarnings("deprecation")
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult rayTraceResult)
{
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult rayTraceResult) {
if (world.isClientSide) return InteractionResult.SUCCESS;
return (world.getBlockEntity(pos) instanceof FluidFunnelTileEntity) && Fluidics.manualFluidHandlerInteraction(player, hand, world, pos, rayTraceResult.getDirection()) ? InteractionResult.CONSUME : InteractionResult.FAIL;
}
@Override
@SuppressWarnings("deprecation")
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block block, BlockPos fromPos, boolean unused)
{ BlockEntity te = world.getBlockEntity(pos); if(te instanceof FluidFunnelTileEntity) ((FluidFunnelTileEntity)te).block_changed(); }
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block block, BlockPos fromPos, boolean unused) {
BlockEntity te = world.getBlockEntity(pos);
if (te instanceof FluidFunnelTileEntity) ((FluidFunnelTileEntity) te).block_changed();
}
@Override
public boolean shouldCheckWeakPower(BlockState state, LevelReader world, BlockPos pos, Direction side)
{ return false; }
public boolean shouldCheckWeakPower(BlockState state, SignalGetter level, BlockPos pos, Direction side) {
return false;
}
}
//--------------------------------------------------------------------------------------------------------------------
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
public static class FluidFunnelTileEntity extends StandardEntityBlocks.StandardBlockEntity
{
public static class FluidFunnelTileEntity extends StandardEntityBlocks.StandardBlockEntity {
public static final int TANK_CAPACITY = 3000;
public static final int TICK_INTERVAL = 10; // ca 500ms
public static final int COLLECTION_INTERVAL = 40; // ca 2000ms, simulates suction delay and saves CPU when not drained.
@ -179,6 +186,8 @@ public class EdFluidFunnel
public static final int MAX_TRACKING_STEPS_PER_CYCLE_INTENSIVE = 1024;
public static final int MAX_TRACK_RADIUS_SQ = MAX_TRACK_RADIUS * MAX_TRACK_RADIUS;
public static final int INTENSIVE_SEARCH_TRIGGER_THRESHOLD = 16;
private final Fluidics.Tank tank_ = new Fluidics.Tank(TANK_CAPACITY, 0, TANK_CAPACITY);
private final LazyOptional<IFluidHandler> fluid_handler_ = tank_.createOutputFluidHandler();
private int tick_timer_ = 0;
private int collection_timer_ = 0;
private int no_fluid_found_counter_ = 0;
@ -186,38 +195,39 @@ public class EdFluidFunnel
private int total_pick_counter_ = 0;
private BlockPos last_pick_pos_ = BlockPos.ZERO;
private ArrayList<Vec3i> search_offsets_ = null;
private final Fluidics.Tank tank_ = new Fluidics.Tank(TANK_CAPACITY, 0, TANK_CAPACITY);
private final LazyOptional<IFluidHandler> fluid_handler_ = tank_.createOutputFluidHandler();
public FluidFunnelTileEntity(BlockPos pos, BlockState state)
{ super(ModContent.getBlockEntityTypeOfBlock(state.getBlock()), pos, state); }
public FluidFunnelTileEntity(BlockPos pos, BlockState state) {
super(ModContent.getBlockEntityTypeOfBlock(state.getBlock()), pos, state);
}
public void readnbt(CompoundTag nbt)
{
public void readnbt(CompoundTag nbt) {
tank_.load(nbt);
}
public void writenbt(CompoundTag nbt)
{
public void writenbt(CompoundTag nbt) {
tank_.save(nbt);
}
public void block_changed()
{ tick_timer_ = TICK_INTERVAL; }
public void block_changed() {
tick_timer_ = TICK_INTERVAL;
}
// BlockEntity -----------------------------------------------------------------------------------------
@Override
public void load(CompoundTag nbt)
{ super.load(nbt); readnbt(nbt); }
public void load(CompoundTag nbt) {
super.load(nbt);
readnbt(nbt);
}
@Override
protected void saveAdditional(CompoundTag nbt)
{ super.saveAdditional(nbt); writenbt(nbt); }
protected void saveAdditional(CompoundTag nbt) {
super.saveAdditional(nbt);
writenbt(nbt);
}
@Override
public void setRemoved()
{
public void setRemoved() {
super.setRemoved();
fluid_handler_.invalidate();
}
@ -225,21 +235,18 @@ public class EdFluidFunnel
// ICapabilityProvider / Output flow handler ----------------------------------------------------------
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing) {
if (capability == ForgeCapabilities.FLUID_HANDLER) return fluid_handler_.cast();
return super.getCapability(capability, facing);
}
// -----------------------------------------------------------------------------------------------------------------
private FluidState get_fluidstate(BlockPos pos)
{
private FluidState get_fluidstate(BlockPos pos) {
return level.getFluidState(pos);
}
private boolean try_pick(BlockPos pos, FluidState fluidstate)
{
private boolean try_pick(BlockPos pos, FluidState fluidstate) {
if (!fluidstate.isSource()) return false;
IFluidHandler hnd = Fluidics.handler(level, pos, null);
FluidStack fs;
@ -254,7 +261,8 @@ public class EdFluidFunnel
level.setBlock(pos, Blocks.AIR.defaultBlockState(), 1 | 2); // ok we can't leave the block, that would be an infinite source of an unknown fluid.
}
}
if((fs==null) || (fs.isEmpty())) return false; // it's marked nonnull but I don't trust every modder - including meself ...
if ((fs == null) || (fs.isEmpty()))
return false; // it's marked nonnull but I don't trust every modder - including meself ...
if (tank_.isEmpty()) {
tank_.setFluid(fs.copy());
} else if (tank_.isFluidEqual(fs)) {
@ -265,8 +273,7 @@ public class EdFluidFunnel
return true;
}
private boolean can_pick(BlockPos pos, FluidState fluidstate)
{
private boolean can_pick(BlockPos pos, FluidState fluidstate) {
if (fluidstate.isSource()) return true;
final IFluidHandler hnd = Fluidics.handler(level, pos, null);
if (hnd == null) return false;
@ -274,8 +281,7 @@ public class EdFluidFunnel
return ((fs != null) && (!fs.isEmpty())) && (fluidstate.getType().isSame(fs.getFluid()));
}
private void rebuild_search_offsets(boolean intensive)
{
private void rebuild_search_offsets(boolean intensive) {
search_offsets_ = new ArrayList<>(9);
search_offsets_.add(new Vec3i(0, 1, 0)); // up first
{
@ -290,14 +296,19 @@ public class EdFluidFunnel
}
}
private boolean try_collect(final BlockPos collection_pos)
{
private boolean try_collect(final BlockPos collection_pos) {
FluidState collection_fluidstate = get_fluidstate(collection_pos);
if (collection_fluidstate.isEmpty()) return false;
Fluid fluid_to_collect = collection_fluidstate.getType();
if ((!tank_.isEmpty()) && (!tank_.getFluid().getFluid().isSame(fluid_to_collect))) return false;
if(try_pick(collection_pos, collection_fluidstate)) { last_pick_pos_ = collection_pos; return true; } // Blocks directly always first. Allows water source blocks to recover/reflow to source blocks.
if((last_pick_pos_==null) || (last_pick_pos_.distSqr(collection_pos) > MAX_TRACK_RADIUS_SQ)) { last_pick_pos_ = collection_pos; search_offsets_ = null; }
if (try_pick(collection_pos, collection_fluidstate)) {
last_pick_pos_ = collection_pos;
return true;
} // Blocks directly always first. Allows water source blocks to recover/reflow to source blocks.
if ((last_pick_pos_ == null) || (last_pick_pos_.distSqr(collection_pos) > MAX_TRACK_RADIUS_SQ)) {
last_pick_pos_ = collection_pos;
search_offsets_ = null;
}
BlockPos pos = last_pick_pos_;
HashSet<BlockPos> checked = new HashSet<>();
Stack<BlockPos> trail = new Stack<>();
@ -305,7 +316,10 @@ public class EdFluidFunnel
checked.add(pos);
int steps = 0;
boolean intensive = (no_fluid_found_counter_ >= INTENSIVE_SEARCH_TRIGGER_THRESHOLD);
if(intensive) { no_fluid_found_counter_ = 0; ++intensive_search_counter_; }
if (intensive) {
no_fluid_found_counter_ = 0;
++intensive_search_counter_;
}
if (search_offsets_ == null) rebuild_search_offsets(intensive);
int max = intensive ? MAX_TRACKING_STEPS_PER_CYCLE_INTENSIVE : MAX_TRACKING_STEPS_PER_CYCLE;
while (++steps <= max) {
@ -336,7 +350,8 @@ public class EdFluidFunnel
no_fluid_found_counter_ = 0;
search_offsets_ = null;
// probability reset, so it's not turteling too far away, mainly for large nether lava seas, not desert lakes.
if((++total_pick_counter_ > 50) && level.random.nextInt(10)==0) last_pick_pos_ = collection_pos;
if ((++total_pick_counter_ > 50) && level.random.nextInt(10) == 0)
last_pick_pos_ = collection_pos;
//println("PASS " + steps + " - " + (pos.subtract(collection_pos)));
return true;
}
@ -354,8 +369,7 @@ public class EdFluidFunnel
return false;
}
public void tick()
{
public void tick() {
if ((level.isClientSide) || (--tick_timer_ > 0)) return;
tick_timer_ = TICK_INTERVAL;
collection_timer_ += TICK_INTERVAL;
@ -399,7 +413,8 @@ public class EdFluidFunnel
}
// Block state
int fill_level = (tank_ == null) ? 0 : (Mth.clamp(tank_.getFluidAmount() / 1000, 0, FluidFunnelBlock.FILL_LEVEL_MAX));
if(funnel_state.getValue(FluidFunnelBlock.FILL_LEVEL) != fill_level) level.setBlock(worldPosition, funnel_state.setValue(FluidFunnelBlock.FILL_LEVEL, fill_level), 2|16);
if (funnel_state.getValue(FluidFunnelBlock.FILL_LEVEL) != fill_level)
level.setBlock(worldPosition, funnel_state.setValue(FluidFunnelBlock.FILL_LEVEL, fill_level), 2 | 16);
if (dirty) setChanged();
}
}

View file

@ -9,6 +9,11 @@
*/
package dev.zontreck.engineerdecor.blocks;
import dev.zontreck.engineerdecor.ModConfig;
import dev.zontreck.engineerdecor.ModContent;
import dev.zontreck.libzontreck.edlibmc.Fluidics;
import dev.zontreck.libzontreck.edlibmc.StandardBlocks;
import dev.zontreck.libzontreck.edlibmc.StandardEntityBlocks;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
@ -25,7 +30,7 @@ import net.minecraft.world.item.Items;
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.SignalGetter;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockBehaviour;
@ -45,72 +50,74 @@ import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.energy.IEnergyStorage;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.items.IItemHandler;
import dev.zontreck.engineerdecor.ModConfig;
import dev.zontreck.engineerdecor.ModContent;
import dev.zontreck.engineerdecor.libmc.StandardBlocks;
import dev.zontreck.engineerdecor.libmc.StandardEntityBlocks;
import dev.zontreck.engineerdecor.libmc.Fluidics;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
public class EdFreezer
{
public static void on_config(int consumption, int cooldown_per_second)
{ FreezerTileEntity.on_config(consumption, cooldown_per_second); }
public class EdFreezer {
public static void on_config(int consumption, int cooldown_per_second) {
FreezerTileEntity.on_config(consumption, cooldown_per_second);
}
//--------------------------------------------------------------------------------------------------------------------
// Block
//--------------------------------------------------------------------------------------------------------------------
public static class FreezerBlock extends StandardBlocks.Horizontal implements StandardEntityBlocks.IStandardEntityBlock<FreezerTileEntity>
{
public static class FreezerBlock extends StandardBlocks.Horizontal implements StandardEntityBlocks.IStandardEntityBlock<FreezerTileEntity> {
public static final int PHASE_MAX = 4;
public static final IntegerProperty PHASE = IntegerProperty.create("phase", 0, PHASE_MAX);
public FreezerBlock(long config, BlockBehaviour.Properties builder, final AABB unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
public FreezerBlock(long config, BlockBehaviour.Properties builder, final AABB unrotatedAABB) {
super(config, builder, unrotatedAABB);
}
@Override
public boolean isBlockEntityTicking(Level world, BlockState state)
{ return true; }
public boolean isBlockEntityTicking(Level world, BlockState state) {
return true;
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext)
{ return Shapes.block(); }
public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) {
return Shapes.block();
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder)
{ super.createBlockStateDefinition(builder); builder.add(PHASE); }
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
super.createBlockStateDefinition(builder);
builder.add(PHASE);
}
@Override
@Nullable
public BlockState getStateForPlacement(BlockPlaceContext context)
{ return super.getStateForPlacement(context).setValue(PHASE, 0); }
public BlockState getStateForPlacement(BlockPlaceContext context) {
return super.getStateForPlacement(context).setValue(PHASE, 0);
}
@Override
@SuppressWarnings("deprecation")
public boolean hasAnalogOutputSignal(BlockState state)
{ return true; }
public boolean hasAnalogOutputSignal(BlockState state) {
return true;
}
@Override
@SuppressWarnings("deprecation")
public int getAnalogOutputSignal(BlockState state, Level world, BlockPos pos)
{ return Mth.clamp((state.getValue(PHASE)*4), 0, 15); }
public int getAnalogOutputSignal(BlockState state, Level world, BlockPos pos) {
return Mth.clamp((state.getValue(PHASE) * 4), 0, 15);
}
@Override
public void setPlacedBy(Level world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack)
{}
public void setPlacedBy(Level world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) {
}
@Override
public boolean hasDynamicDropList()
{ return true; }
public boolean hasDynamicDropList() {
return true;
}
@Override
public List<ItemStack> dropList(BlockState state, Level world, BlockEntity te, boolean explosion)
{
public List<ItemStack> dropList(BlockState state, Level world, BlockEntity te, boolean explosion) {
final List<ItemStack> stacks = new ArrayList<>();
if (world.isClientSide) return stacks;
if (!(te instanceof FreezerTileEntity)) return stacks;
@ -121,8 +128,7 @@ public class EdFreezer
@Override
@SuppressWarnings("deprecation")
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult rayTraceResult)
{
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult rayTraceResult) {
if (player.isShiftKeyDown()) return InteractionResult.PASS;
if (world.isClientSide()) return InteractionResult.SUCCESS;
FreezerTileEntity te = getTe(world, pos);
@ -150,25 +156,27 @@ public class EdFreezer
}
@Override
public boolean shouldCheckWeakPower(BlockState state, LevelReader world, BlockPos pos, Direction side)
{ return false; }
public boolean shouldCheckWeakPower(BlockState state, SignalGetter level, BlockPos pos, Direction side) {
return false;
}
@Override
@OnlyIn(Dist.CLIENT)
public void animateTick(BlockState state, Level world, BlockPos pos, RandomSource rnd)
{}
public void animateTick(BlockState state, Level world, BlockPos pos, RandomSource rnd) {
}
@Nullable
private FreezerTileEntity getTe(Level world, BlockPos pos)
{ final BlockEntity te=world.getBlockEntity(pos); return (!(te instanceof FreezerTileEntity)) ? (null) : ((FreezerTileEntity)te); }
private FreezerTileEntity getTe(Level world, BlockPos pos) {
final BlockEntity te = world.getBlockEntity(pos);
return (!(te instanceof FreezerTileEntity)) ? (null) : ((FreezerTileEntity) te);
}
}
//--------------------------------------------------------------------------------------------------------------------
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
public static class FreezerTileEntity extends StandardEntityBlocks.StandardBlockEntity implements IEnergyStorage
{
public static class FreezerTileEntity extends StandardEntityBlocks.StandardBlockEntity implements IEnergyStorage {
public static final int TICK_INTERVAL = 20;
public static final int MAX_FLUID_LEVEL = 2000;
public static final int MAX_ENERGY_BUFFER = 32000;
@ -186,27 +194,30 @@ public class EdFreezer
private static int cooldown_rate = DEFAULT_COOLDOWN_RATE;
private static int reheat_rate = 1;
private final Fluidics.Tank tank_ = new Fluidics.Tank(TANK_CAPACITY, TANK_CAPACITY, TANK_CAPACITY, fs -> fs.getFluid() == Fluids.WATER);
private final LazyOptional<IItemHandler> item_handler_ = LazyOptional.of(() -> new FreezerItemHandler(this));
private final LazyOptional<IFluidHandler> fluid_handler_ = LazyOptional.of(() -> new Fluidics.SingleTankFluidHandler(tank_));
protected LazyOptional<IEnergyStorage> energy_handler_ = LazyOptional.of(() -> this);
private int tick_timer_;
private int energy_stored_;
private int progress_;
private boolean force_block_update_;
public static void on_config(int consumption, int cooldown_per_second)
{
public FreezerTileEntity(BlockPos pos, BlockState state) {
super(ModContent.getBlockEntityTypeOfBlock(state.getBlock()), pos, state);
}
public static void on_config(int consumption, int cooldown_per_second) {
energy_consumption = Mth.clamp(consumption, 8, 4096);
cooldown_rate = Mth.clamp(cooldown_per_second, 1, 5);
reheat_rate = Mth.clamp(cooldown_per_second / 2, 1, 5);
ModConfig.log("Config freezer energy consumption:" + energy_consumption + "rf/t, cooldown-rate: " + cooldown_rate + "%/s.");
}
public FreezerTileEntity(BlockPos pos, BlockState state)
{ super(ModContent.getBlockEntityTypeOfBlock(state.getBlock()), pos, state); }
public int progress() {
return progress_;
}
public int progress()
{ return progress_; }
public int phase()
{
public int phase() {
if (tank_.getFluidAmount() < 1000) return PHASE_EMPTY;
if (progress_ >= 100) return PHASE_BLUEICE;
if (progress_ >= 70) return PHASE_PACKEDICE;
@ -214,156 +225,125 @@ public class EdFreezer
return PHASE_WATER;
}
public ItemStack getIceItem(boolean extract)
{
public ItemStack getIceItem(boolean extract) {
ItemStack stack;
switch (phase()) {
case PHASE_ICE: stack = new ItemStack(Items.ICE); break;
case PHASE_PACKEDICE: stack = new ItemStack(Items.PACKED_ICE); break;
case PHASE_BLUEICE: stack = new ItemStack(Items.BLUE_ICE); break;
default: return ItemStack.EMPTY;
case PHASE_ICE:
stack = new ItemStack(Items.ICE);
break;
case PHASE_PACKEDICE:
stack = new ItemStack(Items.PACKED_ICE);
break;
case PHASE_BLUEICE:
stack = new ItemStack(Items.BLUE_ICE);
break;
default:
return ItemStack.EMPTY;
}
if (extract) reset_process();
return stack;
}
public int comparator_signal()
{ return phase() * 4; }
public int comparator_signal() {
return phase() * 4;
}
protected void reset_process()
{
// BlockEntity ------------------------------------------------------------------------------
protected void reset_process() {
force_block_update_ = true;
tank_.drain(1000);
tick_timer_ = 0;
progress_ = 0;
}
public void readnbt(CompoundTag nbt)
{
public void readnbt(CompoundTag nbt) {
energy_stored_ = nbt.getInt("energy");
progress_ = nbt.getInt("progress");
tank_.load(nbt);
}
protected void writenbt(CompoundTag nbt)
{
protected void writenbt(CompoundTag nbt) {
nbt.putInt("energy", Mth.clamp(energy_stored_, 0, MAX_ENERGY_BUFFER));
nbt.putInt("progress", Mth.clamp(progress_, 0, 100));
tank_.save(nbt);
}
// BlockEntity ------------------------------------------------------------------------------
// IItemHandler --------------------------------------------------------------------------------
@Override
public void load(CompoundTag nbt)
{ super.load(nbt); readnbt(nbt); }
public void load(CompoundTag nbt) {
super.load(nbt);
readnbt(nbt);
}
@Override
protected void saveAdditional(CompoundTag nbt)
{ super.saveAdditional(nbt); writenbt(nbt); }
protected void saveAdditional(CompoundTag nbt) {
super.saveAdditional(nbt);
writenbt(nbt);
}
// IFluidHandler --------------------------------------------------------------------------------
@Override
public void setRemoved()
{
public void setRemoved() {
super.setRemoved();
energy_handler_.invalidate();
fluid_handler_.invalidate();
item_handler_.invalidate();
}
// IItemHandler --------------------------------------------------------------------------------
private final LazyOptional<IItemHandler> item_handler_ = LazyOptional.of(() -> new FreezerItemHandler(this));
protected static class FreezerItemHandler implements IItemHandler
{
private final FreezerTileEntity te;
FreezerItemHandler(FreezerTileEntity te)
{ this.te = te; }
@Override
public int getSlots()
{ return 1; }
@Override
public int getSlotLimit(int index)
{ return 1; }
@Override
public boolean isItemValid(int slot, @Nonnull ItemStack stack)
{ return false; }
@Override
@Nonnull
public ItemStack getStackInSlot(int index)
{ return (index!=0) ? ItemStack.EMPTY : te.getIceItem(false); }
@Override
@Nonnull
public ItemStack insertItem(int index, @Nonnull ItemStack stack, boolean simulate)
{ return ItemStack.EMPTY; }
@Override
@Nonnull
public ItemStack extractItem(int index, int amount, boolean simulate)
{ return te.getIceItem(!simulate); }
}
// IFluidHandler --------------------------------------------------------------------------------
private final LazyOptional<IFluidHandler> fluid_handler_ = LazyOptional.of(() -> new Fluidics.SingleTankFluidHandler(tank_));
// IEnergyStorage ----------------------------------------------------------------------------
protected LazyOptional<IEnergyStorage> energy_handler_ = LazyOptional.of(() -> this);
@Override
public boolean canExtract() {
return false;
}
@Override
public boolean canExtract()
{ return false; }
public boolean canReceive() {
return true;
}
@Override
public boolean canReceive()
{ return true; }
public int getMaxEnergyStored() {
return MAX_ENERGY_BUFFER;
}
@Override
public int getMaxEnergyStored()
{ return MAX_ENERGY_BUFFER; }
public int getEnergyStored() {
return energy_stored_;
}
@Override
public int getEnergyStored()
{ return energy_stored_; }
public int extractEnergy(int maxExtract, boolean simulate) {
return 0;
}
@Override
public int extractEnergy(int maxExtract, boolean simulate)
{ return 0; }
@Override
public int receiveEnergy(int maxReceive, boolean simulate)
{
public int receiveEnergy(int maxReceive, boolean simulate) {
if (energy_stored_ >= MAX_ENERGY_BUFFER) return 0;
int n = Math.min(maxReceive, (MAX_ENERGY_BUFFER - energy_stored_));
if (n > MAX_ENERGY_TRANSFER) n = MAX_ENERGY_TRANSFER;
if(!simulate) {energy_stored_ += n; setChanged(); }
if (!simulate) {
energy_stored_ += n;
setChanged();
}
return n;
}
// Capability export ----------------------------------------------------------------------------
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing) {
if (capability == ForgeCapabilities.ITEM_HANDLER) return item_handler_.cast();
if (capability == ForgeCapabilities.FLUID_HANDLER) return fluid_handler_.cast();
if (capability == ForgeCapabilities.ENERGY) return energy_handler_.cast();
return super.getCapability(capability, facing);
}
// ITickable ------------------------------------------------------------------------------------
// Capability export ----------------------------------------------------------------------------
@Override
public void tick()
{
public void tick() {
if (level.isClientSide) return;
if (--tick_timer_ > 0) return;
tick_timer_ = TICK_INTERVAL;
@ -397,5 +377,48 @@ public class EdFreezer
}
if (dirty) setChanged();
}
// ITickable ------------------------------------------------------------------------------------
protected static class FreezerItemHandler implements IItemHandler {
private final FreezerTileEntity te;
FreezerItemHandler(FreezerTileEntity te) {
this.te = te;
}
@Override
public int getSlots() {
return 1;
}
@Override
public int getSlotLimit(int index) {
return 1;
}
@Override
public boolean isItemValid(int slot, @Nonnull ItemStack stack) {
return false;
}
@Override
@Nonnull
public ItemStack getStackInSlot(int index) {
return (index != 0) ? ItemStack.EMPTY : te.getIceItem(false);
}
@Override
@Nonnull
public ItemStack insertItem(int index, @Nonnull ItemStack stack, boolean simulate) {
return ItemStack.EMPTY;
}
@Override
@Nonnull
public ItemStack extractItem(int index, int amount, boolean simulate) {
return te.getIceItem(!simulate);
}
}
}
}

View file

@ -8,7 +8,11 @@
*/
package dev.zontreck.engineerdecor.blocks;
import com.mojang.blaze3d.vertex.PoseStack;
import dev.zontreck.engineerdecor.ModConfig;
import dev.zontreck.engineerdecor.ModContent;
import dev.zontreck.libzontreck.edlibmc.*;
import dev.zontreck.libzontreck.edlibmc.Inventories.MappedItemHandler;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.particles.ParticleTypes;
@ -35,7 +39,7 @@ import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.item.crafting.SmeltingRecipe;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.SignalGetter;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockBehaviour;
@ -54,77 +58,72 @@ import net.minecraftforge.energy.IEnergyStorage;
import net.minecraftforge.event.ForgeEventFactory;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.registries.ForgeRegistries;
import dev.zontreck.engineerdecor.ModConfig;
import dev.zontreck.engineerdecor.ModContent;
import dev.zontreck.engineerdecor.libmc.StandardBlocks;
import dev.zontreck.engineerdecor.libmc.StandardEntityBlocks;
import dev.zontreck.engineerdecor.libmc.Auxiliaries;
import dev.zontreck.engineerdecor.libmc.Inventories;
import dev.zontreck.engineerdecor.libmc.Inventories.MappedItemHandler;
import dev.zontreck.engineerdecor.libmc.Inventories.StorageInventory;
import dev.zontreck.engineerdecor.libmc.Networking;
import dev.zontreck.engineerdecor.libmc.RfEnergy;
import dev.zontreck.engineerdecor.libmc.Guis;
import javax.annotation.Nullable;
import java.util.*;
import java.util.stream.Collectors;
public class EdFurnace
{
public static void on_config(int speed_percent, int fuel_efficiency_percent, int boost_energy_per_tick, String accepted_heaters_csv)
{ FurnaceTileEntity.on_config(speed_percent, fuel_efficiency_percent, boost_energy_per_tick, accepted_heaters_csv); }
public class EdFurnace {
public static void on_config(int speed_percent, int fuel_efficiency_percent, int boost_energy_per_tick, String accepted_heaters_csv) {
FurnaceTileEntity.on_config(speed_percent, fuel_efficiency_percent, boost_energy_per_tick, accepted_heaters_csv);
}
//--------------------------------------------------------------------------------------------------------------------
// Block
//--------------------------------------------------------------------------------------------------------------------
public static class FurnaceBlock extends StandardBlocks.Horizontal implements StandardEntityBlocks.IStandardEntityBlock<FurnaceTileEntity>
{
public static class FurnaceBlock extends StandardBlocks.Horizontal implements StandardEntityBlocks.IStandardEntityBlock<FurnaceTileEntity> {
public static final BooleanProperty LIT = BlockStateProperties.LIT;
public FurnaceBlock(long config, BlockBehaviour.Properties properties, final AABB[] unrotatedAABB)
{ super(config, properties, unrotatedAABB); registerDefaultState(super.defaultBlockState().setValue(LIT, false)); }
public FurnaceBlock(long config, BlockBehaviour.Properties properties, final AABB[] unrotatedAABB) {
super(config, properties, unrotatedAABB);
registerDefaultState(super.defaultBlockState().setValue(LIT, false));
}
@Override
public boolean isBlockEntityTicking(Level world, BlockState state)
{ return true; }
public boolean isBlockEntityTicking(Level world, BlockState state) {
return true;
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder)
{ super.createBlockStateDefinition(builder); builder.add(LIT); }
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
super.createBlockStateDefinition(builder);
builder.add(LIT);
}
@Override
@SuppressWarnings("deprecation")
public int getLightEmission(BlockState state, BlockGetter world, BlockPos pos)
{ return state.getValue(LIT) ? super.getLightEmission(state, world, pos) : 0; }
public int getLightEmission(BlockState state, BlockGetter world, BlockPos pos) {
return state.getValue(LIT) ? super.getLightEmission(state, world, pos) : 0;
}
@Override
@Nullable
public BlockState getStateForPlacement(BlockPlaceContext context)
{ return super.getStateForPlacement(context).setValue(LIT, false); }
public BlockState getStateForPlacement(BlockPlaceContext context) {
return super.getStateForPlacement(context).setValue(LIT, false);
}
@Override
@SuppressWarnings("deprecation")
public boolean hasAnalogOutputSignal(BlockState state)
{ return true; }
public boolean hasAnalogOutputSignal(BlockState state) {
return true;
}
@Override
@SuppressWarnings("deprecation")
public int getAnalogOutputSignal(BlockState blockState, Level world, BlockPos pos)
{
public int getAnalogOutputSignal(BlockState blockState, Level world, BlockPos pos) {
BlockEntity te = world.getBlockEntity(pos);
return (te instanceof FurnaceTileEntity) ? ((FurnaceTileEntity) te).getComparatorOutput() : 0;
}
@Override
public boolean shouldCheckWeakPower(BlockState state, LevelReader world, BlockPos pos, Direction side)
{ return false; }
public boolean shouldCheckWeakPower(BlockState state, SignalGetter level, BlockPos pos, Direction side) {
return false;
}
@Override
public void setPlacedBy(Level world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack)
{
public void setPlacedBy(Level world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) {
world.setBlockAndUpdate(pos, state.setValue(LIT, false));
if (world.isClientSide) return;
if ((!stack.hasTag()) || (!stack.getTag().contains("inventory"))) return;
@ -138,8 +137,9 @@ public class EdFurnace
}
@Override
public boolean hasDynamicDropList()
{ return true; }
public boolean hasDynamicDropList() {
return true;
}
@Override
public List<ItemStack> dropList(BlockState state, Level world, final BlockEntity te, boolean explosion) {
@ -164,19 +164,20 @@ public class EdFurnace
@Override
@SuppressWarnings("deprecation")
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult rayTraceResult)
{ return useOpenGui(state, world, pos, player); }
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult rayTraceResult) {
return useOpenGui(state, world, pos, player);
}
@Override
@OnlyIn(Dist.CLIENT)
public void animateTick(BlockState state, Level world, BlockPos pos, RandomSource rnd)
{
public void animateTick(BlockState state, Level world, BlockPos pos, RandomSource rnd) {
if ((state.getBlock() != this) || (!state.getValue(LIT))) return;
final double rv = rnd.nextDouble();
if (rv > 0.5) return;
final double x = 0.5 + pos.getX(), y = 0.5 + pos.getY(), z = 0.5 + pos.getZ();
final double xc = 0.52, xr = rnd.nextDouble() * 0.4 - 0.2, yr = (y - 0.3 + rnd.nextDouble() * 0.2);
if(rv < 0.1d) world.playLocalSound(x, y, z, SoundEvents.FURNACE_FIRE_CRACKLE, SoundSource.BLOCKS, 0.4f, 0.5f, false);
if (rv < 0.1d)
world.playLocalSound(x, y, z, SoundEvents.FURNACE_FIRE_CRACKLE, SoundSource.BLOCKS, 0.4f, 0.5f, false);
switch (state.getValue(HORIZONTAL_FACING)) {
case WEST -> world.addParticle(ParticleTypes.SMOKE, x - xc, yr, z + xr, 0.0, 0.0, 0.0);
case EAST -> world.addParticle(ParticleTypes.SMOKE, x + xc, yr, z + xr, 0.0, 0.0, 0.0);
@ -191,8 +192,7 @@ public class EdFurnace
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
public static class FurnaceTileEntity extends StandardEntityBlocks.StandardBlockEntity implements MenuProvider, Nameable
{
public static class FurnaceTileEntity extends StandardEntityBlocks.StandardBlockEntity implements MenuProvider, Nameable {
private static final RecipeType<SmeltingRecipe> RECIPE_TYPE = RecipeType.SMELTING;
private static final int MAX_BURNTIME = 0x7fff;
private static final int MAX_XP_STORED = 65535;
@ -215,40 +215,18 @@ public class EdFurnace
private static final int AUX_1_SLOT_NO = 10;
// Config ----------------------------------------------------------------------------------
private static final Set<Item> accepted_heaters_ = new HashSet<>();
private static double proc_fuel_efficiency_ = 1.0;
private static double proc_speed_ = 1.2;
private static int boost_energy_consumption = DEFAULT_BOOST_ENERGY * TICK_INTERVAL;
private static final Set<Item> accepted_heaters_ = new HashSet<>();
public static void on_config(int speed_percent, int fuel_efficiency_percent, int boost_energy_per_tick, String accepted_heaters_csv)
{
proc_speed_ = ((double)Mth.clamp(speed_percent, 10, 500)) / 100;
proc_fuel_efficiency_ = ((double) Mth.clamp(fuel_efficiency_percent, 10, 500)) / 100;
boost_energy_consumption = TICK_INTERVAL * Mth.clamp(boost_energy_per_tick, 4, 4096);
{
List<String> heater_resource_locations = Arrays.stream(accepted_heaters_csv.toLowerCase().split("[\\s,;]+")).map(String::trim).toList();
accepted_heaters_.clear();
for(String rlstr: heater_resource_locations) {
try {
ResourceLocation rl = new ResourceLocation(rlstr);
Item heater = ForgeRegistries.ITEMS.getValue(rl);
if((heater==null) || (heater==Items.AIR)) {
ModConfig.log("Furnace accepted heater config: Skipped '" + rl + "', item not found/mod not installed.");
} else {
accepted_heaters_.add(heater);
}
} catch(Throwable e) {
Auxiliaries.logError("Furnace accepted heater config invalid: '" + rlstr + "', not added.");
}
}
}
Auxiliaries.logInfo("Config lab furnace speed:" + (proc_speed_*100) + "%, efficiency:" + (proc_fuel_efficiency_*100) + "%, boost: " + (boost_energy_consumption/TICK_INTERVAL) + "rf/t.");
Auxiliaries.logInfo("Config lab furnace accepted heaters: " + accepted_heaters_.stream().map(item->Auxiliaries.getResourceLocation(item).toString()).collect(Collectors.joining(",")) + ".");
}
private final Inventories.StorageInventory inventory_;
// DecorFurnaceTileEntity -----------------------------------------------------------------------------
private final LazyOptional<IItemHandler> item_extraction_handler_;
private final LazyOptional<IItemHandler> item_insertion_handler_;
private final LazyOptional<IItemHandler> item_fuel_insertion_handler_;
private final RfEnergy.Battery battery_ = new RfEnergy.Battery(boost_energy_consumption * 16, boost_energy_consumption, 0);
private final LazyOptional<IEnergyStorage> energy_handler_ = battery_.createEnergyHandler();
private int tick_timer_;
private int fifo_timer_;
private double proc_time_elapsed_;
@ -259,21 +237,42 @@ public class EdFurnace
private @Nullable Recipe<?> current_recipe_ = null;
private int fuel_burntime_;
private int field_proc_time_elapsed_;
private boolean heater_inserted_ = false;
private final StorageInventory inventory_;
private final LazyOptional<IItemHandler> item_extraction_handler_;
private final LazyOptional<IItemHandler> item_insertion_handler_;
private final LazyOptional<IItemHandler> item_fuel_insertion_handler_;
private final RfEnergy.Battery battery_ = new RfEnergy.Battery(boost_energy_consumption * 16, boost_energy_consumption, 0);
private final LazyOptional<IEnergyStorage> energy_handler_ = battery_.createEnergyHandler();
public FurnaceTileEntity(BlockPos pos, BlockState state)
{
super(ModContent.getBlockEntityTypeOfBlock(state.getBlock()), pos, state);
inventory_ = new StorageInventory(this, NUM_OF_SLOTS) {
protected final ContainerData fields = new ContainerData() {
@Override
public void setItem(int index, ItemStack stack)
{
public int getCount() {
return FurnaceTileEntity.NUM_OF_FIELDS;
}
@Override
public int get(int id) {
return switch (id) {
case 0 -> FurnaceTileEntity.this.burntime_left_;
case 1 -> FurnaceTileEntity.this.fuel_burntime_;
case 2 -> FurnaceTileEntity.this.field_proc_time_elapsed_;
case 3 -> FurnaceTileEntity.this.proc_time_needed_;
case 4 -> FurnaceTileEntity.this.field_is_burning_;
default -> 0;
};
}
@Override
public void set(int id, int value) {
switch (id) {
case 0 -> FurnaceTileEntity.this.burntime_left_ = value;
case 1 -> FurnaceTileEntity.this.fuel_burntime_ = value;
case 2 -> FurnaceTileEntity.this.field_proc_time_elapsed_ = value;
case 3 -> FurnaceTileEntity.this.proc_time_needed_ = value;
case 4 -> FurnaceTileEntity.this.field_is_burning_ = value;
}
}
};
private boolean heater_inserted_ = false;
public FurnaceTileEntity(BlockPos pos, BlockState state) {
super(ModContent.getBlockEntityTypeOfBlock(state.getBlock()), pos, state);
inventory_ = new Inventories.StorageInventory(this, NUM_OF_SLOTS) {
@Override
public void setItem(int index, ItemStack stack) {
ItemStack slot_stack = stacks_.get(index);
boolean already_in_slot = (!stack.isEmpty()) && (Inventories.areItemStacksIdentical(stack, slot_stack));
stacks_.set(index, stack);
@ -317,16 +316,63 @@ public class EdFurnace
);
}
public CompoundTag reset_getnbt()
public static void on_config(int speed_percent, int fuel_efficiency_percent, int boost_energy_per_tick, String accepted_heaters_csv) {
proc_speed_ = ((double) Mth.clamp(speed_percent, 10, 500)) / 100;
proc_fuel_efficiency_ = ((double) Mth.clamp(fuel_efficiency_percent, 10, 500)) / 100;
boost_energy_consumption = TICK_INTERVAL * Mth.clamp(boost_energy_per_tick, 4, 4096);
{
List<String> heater_resource_locations = Arrays.stream(accepted_heaters_csv.toLowerCase().split("[\\s,;]+")).map(String::trim).toList();
accepted_heaters_.clear();
for (String rlstr : heater_resource_locations) {
try {
ResourceLocation rl = new ResourceLocation(rlstr);
Item heater = ForgeRegistries.ITEMS.getValue(rl);
if ((heater == null) || (heater == Items.AIR)) {
ModConfig.log("Furnace accepted heater config: Skipped '" + rl + "', item not found/mod not installed.");
} else {
accepted_heaters_.add(heater);
}
} catch (Throwable e) {
Auxiliaries.logError("Furnace accepted heater config invalid: '" + rlstr + "', not added.");
}
}
}
Auxiliaries.logInfo("Config lab furnace speed:" + (proc_speed_ * 100) + "%, efficiency:" + (proc_fuel_efficiency_ * 100) + "%, boost: " + (boost_energy_consumption / TICK_INTERVAL) + "rf/t.");
Auxiliaries.logInfo("Config lab furnace accepted heaters: " + accepted_heaters_.stream().map(item -> Auxiliaries.getResourceLocation(item).toString()).collect(Collectors.joining(",")) + ".");
}
@Nullable
public static <T extends AbstractCookingRecipe> T getSmeltingResult(RecipeType<T> recipe_type, Level world, ItemStack stack) {
if (stack.isEmpty()) return null;
Container inventory = new SimpleContainer(3);
inventory.setItem(0, stack);
return world.getRecipeManager().getRecipeFor(recipe_type, inventory, world).orElse(null);
}
public static int getFuelBurntime(Level world, ItemStack stack) {
if (stack.isEmpty()) return 0;
int t = ForgeHooks.getBurnTime(stack, null);
return Math.max(t, 0);
}
public static boolean isFuel(Level world, ItemStack stack) {
return (getFuelBurntime(world, stack) > 0) || (stack.getItem() == Items.LAVA_BUCKET);
}
public static boolean canSmelt(Level world, final ItemStack stack) {
return getSmeltingResult(RECIPE_TYPE, world, stack) != null;
}
// BlockEntity ------------------------------------------------------------------------------
public CompoundTag reset_getnbt() {
CompoundTag nbt = new CompoundTag();
writenbt(nbt);
reset();
return nbt;
}
public void reset()
{
public void reset() {
inventory_.clearContent();
proc_time_elapsed_ = 0;
proc_time_needed_ = 0;
@ -338,8 +384,7 @@ public class EdFurnace
current_recipe_ = null;
}
public void readnbt(CompoundTag nbt)
{
public void readnbt(CompoundTag nbt) {
burntime_left_ = nbt.getInt("BurnTime");
proc_time_elapsed_ = nbt.getInt("CookTime");
proc_time_needed_ = nbt.getInt("CookTimeTotal");
@ -349,8 +394,9 @@ public class EdFurnace
inventory_.load(nbt);
}
protected void writenbt(CompoundTag nbt)
{
// INamedContainerProvider / Nameable ------------------------------------------------------
protected void writenbt(CompoundTag nbt) {
nbt.putInt("BurnTime", Mth.clamp(burntime_left_, 0, MAX_BURNTIME));
nbt.putInt("CookTime", Mth.clamp((int) proc_time_elapsed_, 0, MAX_BURNTIME));
nbt.putInt("CookTimeTotal", Mth.clamp(proc_time_needed_, 0, MAX_BURNTIME));
@ -360,8 +406,7 @@ public class EdFurnace
inventory_.save(nbt);
}
public int getComparatorOutput()
{
public int getComparatorOutput() {
if (inventory_.getItem(FIFO_FUEL_0_SLOT_NO).isEmpty() && inventory_.getItem(FIFO_FUEL_1_SLOT_NO).isEmpty() && inventory_.getItem(SMELTING_FUEL_SLOT_NO).isEmpty()) {
return 0; // fuel completely empty
} else {
@ -373,19 +418,22 @@ public class EdFurnace
}
}
// BlockEntity ------------------------------------------------------------------------------
@Override
public void load(CompoundTag nbt) {
super.load(nbt);
readnbt(nbt);
}
// IContainerProvider ----------------------------------------------------------------------
@Override
public void load(CompoundTag nbt)
{ super.load(nbt); readnbt(nbt); }
protected void saveAdditional(CompoundTag nbt) {
super.saveAdditional(nbt);
writenbt(nbt);
}
@Override
protected void saveAdditional(CompoundTag nbt)
{ super.saveAdditional(nbt); writenbt(nbt); }
@Override
public void setRemoved()
{
public void setRemoved() {
super.setRemoved();
item_extraction_handler_.invalidate();
item_insertion_handler_.invalidate();
@ -393,68 +441,41 @@ public class EdFurnace
energy_handler_.invalidate();
}
// INamedContainerProvider / Nameable ------------------------------------------------------
@Override
public Component getName()
{ return Auxiliaries.localizable(getBlockState().getBlock().getDescriptionId()); }
@Override
public boolean hasCustomName()
{ return false; }
@Override
public Component getCustomName()
{ return getName(); }
// IContainerProvider ----------------------------------------------------------------------
@Override
public Component getDisplayName()
{ return Nameable.super.getDisplayName(); }
@Override
public AbstractContainerMenu createMenu(int id, Inventory inventory, Player player )
{ return new FurnaceContainer(id, inventory, inventory_, ContainerLevelAccess.create(level, worldPosition), fields); }
// Fields -----------------------------------------------------------------------------------------------
protected final ContainerData fields = new ContainerData()
{
@Override
public int getCount()
{ return FurnaceTileEntity.NUM_OF_FIELDS; }
@Override
public int get(int id)
{
return switch(id) {
case 0 -> FurnaceTileEntity.this.burntime_left_;
case 1 -> FurnaceTileEntity.this.fuel_burntime_;
case 2 -> FurnaceTileEntity.this.field_proc_time_elapsed_;
case 3 -> FurnaceTileEntity.this.proc_time_needed_;
case 4 -> FurnaceTileEntity.this.field_is_burning_;
default -> 0;
};
public Component getName() {
return Auxiliaries.localizable(getBlockState().getBlock().getDescriptionId());
}
@Override
public void set(int id, int value)
{
switch(id) {
case 0 -> FurnaceTileEntity.this.burntime_left_ = value;
case 1 -> FurnaceTileEntity.this.fuel_burntime_ = value;
case 2 -> FurnaceTileEntity.this.field_proc_time_elapsed_ = value;
case 3 -> FurnaceTileEntity.this.proc_time_needed_ = value;
case 4 -> FurnaceTileEntity.this.field_is_burning_ = value;
}
}
};
// Capability export ----------------------------------------------------------------------------
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
public boolean hasCustomName() {
return false;
}
// ITickableTileEntity -------------------------------------------------------------------------
@Override
public Component getCustomName() {
return getName();
}
// Furnace -------------------------------------------------------------------------------------
@Override
public Component getDisplayName() {
return Nameable.super.getDisplayName();
}
@Override
public AbstractContainerMenu createMenu(int id, Inventory inventory, Player player) {
return new FurnaceContainer(id, inventory, inventory_, ContainerLevelAccess.create(level, worldPosition), fields);
}
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing) {
if (capability == ForgeCapabilities.ITEM_HANDLER) {
if (facing == Direction.UP) return item_insertion_handler_.cast();
if (facing == Direction.DOWN) return item_extraction_handler_.cast();
@ -465,11 +486,8 @@ public class EdFurnace
return super.getCapability(capability, facing);
}
// ITickableTileEntity -------------------------------------------------------------------------
@Override
public void tick()
{
public void tick() {
if (--tick_timer_ > 0) return;
tick_timer_ = TICK_INTERVAL;
final BlockState state = level.getBlockState(worldPosition);
@ -508,7 +526,8 @@ public class EdFurnace
if (!fuel.isEmpty()) {
Item fuel_item = fuel.getItem();
fuel.shrink(1);
if(fuel.isEmpty()) inventory_.setItem(SMELTING_FUEL_SLOT_NO, fuel_item.getCraftingRemainingItem(fuel));
if (fuel.isEmpty())
inventory_.setItem(SMELTING_FUEL_SLOT_NO, fuel_item.getCraftingRemainingItem(fuel));
}
}
}
@ -540,22 +559,11 @@ public class EdFurnace
field_proc_time_elapsed_ = (int) proc_time_elapsed_;
}
// Furnace -------------------------------------------------------------------------------------
@Nullable
public static <T extends AbstractCookingRecipe> T getSmeltingResult(RecipeType<T> recipe_type, Level world, ItemStack stack)
{
if(stack.isEmpty()) return null;
Container inventory = new SimpleContainer(3);
inventory.setItem(0, stack);
return world.getRecipeManager().getRecipeFor(recipe_type, inventory, world).orElse(null);
public boolean burning() {
return burntime_left_ > 0;
}
public boolean burning()
{ return burntime_left_ > 0; }
public int getSmeltingTimeNeeded(Level world, ItemStack stack)
{
public int getSmeltingTimeNeeded(Level world, ItemStack stack) {
if (stack.isEmpty()) return 0;
AbstractCookingRecipe recipe = getSmeltingResult(RECIPE_TYPE, world, stack);
if (recipe == null) return 0;
@ -563,8 +571,7 @@ public class EdFurnace
return (t <= 0) ? DEFAULT_SMELTING_TIME : t;
}
private boolean transferItems(final int index_from, final int index_to, int count)
{
private boolean transferItems(final int index_from, final int index_to, int count) {
ItemStack from = inventory_.getItem(index_from);
if (from.isEmpty()) return false;
ItemStack to = inventory_.getItem(index_to);
@ -593,20 +600,19 @@ public class EdFurnace
return changed;
}
protected boolean canSmeltCurrentItem()
{
protected boolean canSmeltCurrentItem() {
if ((currentRecipe() == null) || (inventory_.getItem(SMELTING_INPUT_SLOT_NO).isEmpty())) return false;
final ItemStack recipe_result_items = getSmeltingResult(inventory_.getItem(SMELTING_INPUT_SLOT_NO));
if (recipe_result_items.isEmpty()) return false;
final ItemStack result_stack = inventory_.getItem(SMELTING_OUTPUT_SLOT_NO);
if (result_stack.isEmpty()) return true;
if(!result_stack.sameItem(recipe_result_items)) return false;
if(result_stack.getCount() + recipe_result_items.getCount() <= inventory_.getMaxStackSize() && result_stack.getCount() + recipe_result_items.getCount() <= result_stack.getMaxStackSize()) return true;
if (!result_stack.is(recipe_result_items.getItem())) return false;
if (result_stack.getCount() + recipe_result_items.getCount() <= inventory_.getMaxStackSize() && result_stack.getCount() + recipe_result_items.getCount() <= result_stack.getMaxStackSize())
return true;
return result_stack.getCount() + recipe_result_items.getCount() <= recipe_result_items.getMaxStackSize();
}
protected void smeltCurrentItem()
{
protected void smeltCurrentItem() {
if (!canSmeltCurrentItem()) return;
final ItemStack smelting_input_stack = inventory_.getItem(SMELTING_INPUT_SLOT_NO);
final ItemStack recipe_result_items = getSmeltingResult(smelting_input_stack);
@ -621,18 +627,7 @@ public class EdFurnace
xp_stored_ += xp;
}
public static int getFuelBurntime(Level world, ItemStack stack)
{
if(stack.isEmpty()) return 0;
int t = ForgeHooks.getBurnTime(stack, null);
return Math.max(t, 0);
}
public static boolean isFuel(Level world, ItemStack stack)
{ return (getFuelBurntime(world, stack) > 0) || (stack.getItem()==Items.LAVA_BUCKET); }
public int consumeSmeltingExperience(ItemStack stack)
{
public int consumeSmeltingExperience(ItemStack stack) {
if (xp_stored_ < 1) return 0;
float xp = xp_stored_;
if (xp >= 15) xp /= 2;
@ -641,119 +636,48 @@ public class EdFurnace
return (int) xp;
}
public ItemStack getSmeltingResult(final ItemStack stack)
{ return (currentRecipe()==null) ? (ItemStack.EMPTY) : (currentRecipe().getResultItem()); }
public ItemStack getSmeltingResult(final ItemStack stack) {
return (currentRecipe() == null) ? (ItemStack.EMPTY) : (currentRecipe().getResultItem(getLevel().registryAccess()));
}
public float getCurrentSmeltingXp(final ItemStack stack)
{
public float getCurrentSmeltingXp(final ItemStack stack) {
float xp = (currentRecipe() instanceof AbstractCookingRecipe) ? (((AbstractCookingRecipe) currentRecipe()).getExperience()) : (0);
return (xp <= 0) ? 0.7f : xp; // default value for recipes without defined xp
}
public static boolean canSmelt(Level world, final ItemStack stack)
{ return getSmeltingResult(RECIPE_TYPE, world, stack) != null; }
@Nullable
protected Recipe<?> currentRecipe()
{ return current_recipe_; }
protected Recipe<?> currentRecipe() {
return current_recipe_;
}
protected void updateCurrentRecipe()
{ setCurrentRecipe(getSmeltingResult(RECIPE_TYPE, getLevel(), inventory_.getItem(SMELTING_INPUT_SLOT_NO))); }
protected void updateCurrentRecipe() {
setCurrentRecipe(getSmeltingResult(RECIPE_TYPE, getLevel(), inventory_.getItem(SMELTING_INPUT_SLOT_NO)));
}
protected void setCurrentRecipe(Recipe<?> recipe)
{ current_recipe_ = recipe; }
protected void setCurrentRecipe(Recipe<?> recipe) {
current_recipe_ = recipe;
}
}
//--------------------------------------------------------------------------------------------------------------------
// Container slots
//--------------------------------------------------------------------------------------------------------------------
public static class FurnaceContainer extends AbstractContainerMenu implements Networking.INetworkSynchronisableContainer
{
public static class FurnaceContainer extends AbstractContainerMenu implements Networking.INetworkSynchronisableContainer {
// Slots --------------------------------------------------------------------------------------------
public static class OutputSlot extends Slot
{
private final Container inventory_;
private final Player player_;
private int removeCount = 0;
public OutputSlot(Player player, Container inventory, int index, int xpos, int ypos)
{ super(inventory, index, xpos, ypos); inventory_ = inventory; player_ = player; }
@Override
public boolean mayPlace(ItemStack stack)
{ return false; }
@Override
public ItemStack remove(int amount)
{ removeCount += hasItem() ? Math.min(amount, getItem().getCount()) : 0; return super.remove(amount); }
@Override
public void onTake(Player thePlayer, ItemStack stack)
{ checkTakeAchievements(stack); super.onTake(thePlayer, stack); }
@Override
protected void onQuickCraft(ItemStack stack, int amount)
{ removeCount += amount; checkTakeAchievements(stack); }
@Override
protected void checkTakeAchievements(ItemStack stack)
{
stack.onCraftedBy(player_.level, player_, removeCount);
if((!player_.level.isClientSide()) && (inventory_ instanceof StorageInventory) &&
((((StorageInventory)inventory_).getBlockEntity()) instanceof final FurnaceTileEntity te)
) {
int xp = te.consumeSmeltingExperience(stack);
while(xp > 0) {
int k = ExperienceOrb.getExperienceValue(xp);
xp -= k;
player_.level.addFreshEntity((new ExperienceOrb(player_.level, player_.blockPosition().getX(), player_.blockPosition().getY()+0.5, player_.blockPosition().getZ()+0.5, k)));
}
}
removeCount = 0;
ForgeEventFactory.firePlayerSmeltedEvent(player_, stack);
}
}
public static class FuelSlot extends Slot
{
private final FurnaceContainer container_;
public FuelSlot(Container inventory, int index, int xpos, int ypos, FurnaceContainer container)
{ super(inventory, index, xpos, ypos); container_=container; }
@Override
public boolean mayPlace(ItemStack stack)
{ return isBucket(stack) || (FurnaceTileEntity.isFuel(container_.world(), stack)); }
@Override
public int getMaxStackSize(ItemStack stack)
{ return isBucket(stack) ? 1 : super.getMaxStackSize(stack); }
protected static boolean isBucket(ItemStack stack)
{ return (stack.getItem()==Items.BUCKET); }
}
// Container ----------------------------------------------------------------------------------------
private static final int PLAYER_INV_START_SLOTNO = 11;
protected final Player player_;
// Container ----------------------------------------------------------------------------------------
protected final Container inventory_;
protected final ContainerLevelAccess wpc_;
private final ContainerData fields_;
private final RecipeType<? extends AbstractCookingRecipe> recipe_type_;
public int field(int index) { return fields_.get(index); }
public Player player() { return player_ ; }
public Container inventory() { return inventory_ ; }
public Level world() { return player_.level; }
public FurnaceContainer(int cid, Inventory player_inventory)
{ this(cid, player_inventory, new SimpleContainer(FurnaceTileEntity.NUM_OF_SLOTS), ContainerLevelAccess.NULL, new SimpleContainerData(FurnaceTileEntity.NUM_OF_FIELDS)); }
private FurnaceContainer(int cid, Inventory player_inventory, Container block_inventory, ContainerLevelAccess wpc, ContainerData fields)
{
public FurnaceContainer(int cid, Inventory player_inventory) {
this(cid, player_inventory, new SimpleContainer(FurnaceTileEntity.NUM_OF_SLOTS), ContainerLevelAccess.NULL, new SimpleContainerData(FurnaceTileEntity.NUM_OF_FIELDS));
}
private FurnaceContainer(int cid, Inventory player_inventory, Container block_inventory, ContainerLevelAccess wpc, ContainerData fields) {
super(ModContent.getMenuType("small_lab_furnace"), cid); // @todo: class mapping
player_ = player_inventory.player;
inventory_ = block_inventory;
@ -782,29 +706,49 @@ public class EdFurnace
this.addDataSlots(fields_); // === Add reference holders
}
@Override
public boolean stillValid(Player player)
{ return inventory_.stillValid(player); }
public int field(int index) {
return fields_.get(index);
}
public Player player() {
return player_;
}
public Container inventory() {
return inventory_;
}
public Level world() {
return player_.level();
}
@Override
public ItemStack quickMoveStack(Player player, int index)
{
public boolean stillValid(Player player) {
return inventory_.stillValid(player);
}
@Override
public ItemStack quickMoveStack(Player player, int index) {
Slot slot = getSlot(index);
if ((slot == null) || (!slot.hasItem())) return ItemStack.EMPTY;
ItemStack slot_stack = slot.getItem();
ItemStack transferred = slot_stack.copy();
if ((index == 2) || (index == 7) || (index == 8)) {
// Output slots
if(!moveItemStackTo(slot_stack, PLAYER_INV_START_SLOTNO, PLAYER_INV_START_SLOTNO+36, true)) return ItemStack.EMPTY;
if (!moveItemStackTo(slot_stack, PLAYER_INV_START_SLOTNO, PLAYER_INV_START_SLOTNO + 36, true))
return ItemStack.EMPTY;
slot.onQuickCraft(slot_stack, transferred);
} else if ((index == 0) || (index == 3) || (index == 4)) {
// Input slots
if(!moveItemStackTo(slot_stack, PLAYER_INV_START_SLOTNO, PLAYER_INV_START_SLOTNO+36, false)) return ItemStack.EMPTY;
if (!moveItemStackTo(slot_stack, PLAYER_INV_START_SLOTNO, PLAYER_INV_START_SLOTNO + 36, false))
return ItemStack.EMPTY;
} else if ((index == 1) || (index == 5) || (index == 6)) {
// Fuel slots
if(!moveItemStackTo(slot_stack, PLAYER_INV_START_SLOTNO, PLAYER_INV_START_SLOTNO+36, false)) return ItemStack.EMPTY;
if (!moveItemStackTo(slot_stack, PLAYER_INV_START_SLOTNO, PLAYER_INV_START_SLOTNO + 36, false))
return ItemStack.EMPTY;
} else if ((index == 9) || (index == 10)) {
if(!moveItemStackTo(slot_stack, PLAYER_INV_START_SLOTNO, PLAYER_INV_START_SLOTNO+36, false)) return ItemStack.EMPTY;
if (!moveItemStackTo(slot_stack, PLAYER_INV_START_SLOTNO, PLAYER_INV_START_SLOTNO + 36, false))
return ItemStack.EMPTY;
} else if ((index >= PLAYER_INV_START_SLOTNO) && (index <= PLAYER_INV_START_SLOTNO + 36)) {
// Player inventory
if (FurnaceTileEntity.canSmelt(world(), slot_stack)) {
@ -813,7 +757,7 @@ public class EdFurnace
(!moveItemStackTo(slot_stack, 3, 4, false)) && // fifo0
(!moveItemStackTo(slot_stack, 4, 5, false)) // fifo1
) return ItemStack.EMPTY;
} else if(FurnaceTileEntity.isFuel(player_.level, slot_stack)) {
} else if (FurnaceTileEntity.isFuel(player_.level(), slot_stack)) {
if (
(!moveItemStackTo(slot_stack, 1, 2, false)) && // fuel input
(!moveItemStackTo(slot_stack, 5, 6, false)) && // fuel fifo0
@ -821,7 +765,8 @@ public class EdFurnace
) return ItemStack.EMPTY;
} else if ((index >= PLAYER_INV_START_SLOTNO) && (index < PLAYER_INV_START_SLOTNO + 27)) {
// player inventory --> player hotbar
if(!moveItemStackTo(slot_stack, PLAYER_INV_START_SLOTNO+27, PLAYER_INV_START_SLOTNO+36, false)) return ItemStack.EMPTY;
if (!moveItemStackTo(slot_stack, PLAYER_INV_START_SLOTNO + 27, PLAYER_INV_START_SLOTNO + 36, false))
return ItemStack.EMPTY;
} else if ((index >= PLAYER_INV_START_SLOTNO + 27) && (index < PLAYER_INV_START_SLOTNO + 36) && (!moveItemStackTo(slot_stack, PLAYER_INV_START_SLOTNO, PLAYER_INV_START_SLOTNO + 27, false))) {
// player hotbar --> player inventory
return ItemStack.EMPTY;
@ -841,27 +786,102 @@ public class EdFurnace
return transferred;
}
// INetworkSynchronisableContainer ---------------------------------------------------------
@OnlyIn(Dist.CLIENT)
public void onGuiAction(CompoundTag nbt) {
Networking.PacketContainerSyncClientToServer.sendToServer(containerId, nbt);
}
@OnlyIn(Dist.CLIENT)
public void onGuiAction(CompoundTag nbt)
{ Networking.PacketContainerSyncClientToServer.sendToServer(containerId, nbt); }
@OnlyIn(Dist.CLIENT)
public void onGuiAction(String key, int value)
{
public void onGuiAction(String key, int value) {
CompoundTag nbt = new CompoundTag();
nbt.putInt(key, value);
Networking.PacketContainerSyncClientToServer.sendToServer(containerId, nbt);
}
@Override
public void onServerPacketReceived(int windowId, CompoundTag nbt)
{}
// INetworkSynchronisableContainer ---------------------------------------------------------
@Override
public void onClientPacketReceived(int windowId, Player player, CompoundTag nbt)
{}
public void onServerPacketReceived(int windowId, CompoundTag nbt) {
}
@Override
public void onClientPacketReceived(int windowId, Player player, CompoundTag nbt) {
}
public static class OutputSlot extends Slot {
private final Container inventory_;
private final Player player_;
private int removeCount = 0;
public OutputSlot(Player player, Container inventory, int index, int xpos, int ypos) {
super(inventory, index, xpos, ypos);
inventory_ = inventory;
player_ = player;
}
@Override
public boolean mayPlace(ItemStack stack) {
return false;
}
@Override
public ItemStack remove(int amount) {
removeCount += hasItem() ? Math.min(amount, getItem().getCount()) : 0;
return super.remove(amount);
}
@Override
public void onTake(Player thePlayer, ItemStack stack) {
checkTakeAchievements(stack);
super.onTake(thePlayer, stack);
}
@Override
protected void onQuickCraft(ItemStack stack, int amount) {
removeCount += amount;
checkTakeAchievements(stack);
}
@Override
protected void checkTakeAchievements(ItemStack stack) {
stack.onCraftedBy(player_.level(), player_, removeCount);
if ((!player_.level().isClientSide()) && (inventory_ instanceof Inventories.StorageInventory) &&
((((Inventories.StorageInventory) inventory_).getBlockEntity()) instanceof final FurnaceTileEntity te)
) {
int xp = te.consumeSmeltingExperience(stack);
while (xp > 0) {
int k = ExperienceOrb.getExperienceValue(xp);
xp -= k;
player_.level().addFreshEntity((new ExperienceOrb(player_.level(), player_.blockPosition().getX(), player_.blockPosition().getY() + 0.5, player_.blockPosition().getZ() + 0.5, k)));
}
}
removeCount = 0;
ForgeEventFactory.firePlayerSmeltedEvent(player_, stack);
}
}
public static class FuelSlot extends Slot {
private final FurnaceContainer container_;
public FuelSlot(Container inventory, int index, int xpos, int ypos, FurnaceContainer container) {
super(inventory, index, xpos, ypos);
container_ = container;
}
protected static boolean isBucket(ItemStack stack) {
return (stack.getItem() == Items.BUCKET);
}
@Override
public boolean mayPlace(ItemStack stack) {
return isBucket(stack) || (FurnaceTileEntity.isFuel(container_.world(), stack));
}
@Override
public int getMaxStackSize(ItemStack stack) {
return isBucket(stack) ? 1 : super.getMaxStackSize(stack);
}
}
}
@ -870,27 +890,30 @@ public class EdFurnace
//--------------------------------------------------------------------------------------------------------------------
@OnlyIn(Dist.CLIENT)
public static class FurnaceGui extends Guis.ContainerGui<FurnaceContainer>
{
public FurnaceGui(FurnaceContainer container, Inventory player_inventory, Component title)
{ super(container, player_inventory, title, "textures/gui/small_lab_furnace_gui.png"); }
public static class FurnaceGui extends Guis.ContainerGui<FurnaceContainer> {
public FurnaceGui(FurnaceContainer container, Inventory player_inventory, Component title) {
super(container, player_inventory, title, "textures/gui/small_lab_furnace_gui.png");
}
@Override
protected void renderBgWidgets(PoseStack mx, float partialTicks, int mouseX, int mouseY)
{
protected void renderBgWidgets(GuiGraphics mx, float partialTicks, int mouseX, int mouseY) {
final int x0 = leftPos, y0 = topPos, w = imageWidth, h = imageHeight;
if (getMenu().field(4) != 0) {
final int k = flame_px(13);
blit(mx, x0+59, y0+36+12-k, 176, 12-k, 14, k+1);
mx.blit(getBackgroundImage(), x0 + 59, y0 + 36 + 12 - k, 176, 12 - k, 14, k + 1);
}
blit(mx, x0+79, y0+36, 176, 15, 1+progress_px(17), 15);
mx.blit(getBackgroundImage(), x0 + 79, y0 + 36, 176, 15, 1 + progress_px(17), 15);
}
private int progress_px(int pixels)
{ final int tc=getMenu().field(2), T=getMenu().field(3); return ((T>0) && (tc>0)) ? (tc * pixels / T) : (0); }
private int progress_px(int pixels) {
final int tc = getMenu().field(2), T = getMenu().field(3);
return ((T > 0) && (tc > 0)) ? (tc * pixels / T) : (0);
}
private int flame_px(int pixels)
{ int ibt = getMenu().field(1); return ((getMenu().field(0) * pixels) / ((ibt>0) ? (ibt) : (FurnaceTileEntity.DEFAULT_SMELTING_TIME))); }
private int flame_px(int pixels) {
int ibt = getMenu().field(1);
return ((getMenu().field(0) * pixels) / ((ibt > 0) ? (ibt) : (FurnaceTileEntity.DEFAULT_SMELTING_TIME)));
}
}
}

View file

@ -9,6 +9,8 @@
*/
package dev.zontreck.engineerdecor.blocks;
import dev.zontreck.libzontreck.edlibmc.Auxiliaries;
import dev.zontreck.libzontreck.edlibmc.StandardBlocks;
import net.minecraft.core.Direction;
import net.minecraft.network.chat.Component;
import net.minecraft.world.item.DyeColor;
@ -20,35 +22,37 @@ import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import dev.zontreck.engineerdecor.libmc.StandardBlocks;
import dev.zontreck.engineerdecor.libmc.Auxiliaries;
import javax.annotation.Nullable;
import java.util.List;
public class EdGlassBlock extends StainedGlassBlock implements StandardBlocks.IStandardBlock
{
public EdGlassBlock(long config, BlockBehaviour.Properties properties)
{ super(DyeColor.BLACK, properties); }
public class EdGlassBlock extends StainedGlassBlock implements StandardBlocks.IStandardBlock {
public EdGlassBlock(long config, BlockBehaviour.Properties properties) {
super(DyeColor.BLACK, properties);
}
@Override
@OnlyIn(Dist.CLIENT)
public void appendHoverText(ItemStack stack, @Nullable BlockGetter world, List<Component> tooltip, TooltipFlag flag)
{ Auxiliaries.Tooltip.addInformation(stack, world, tooltip, flag, true); }
public void appendHoverText(ItemStack stack, @Nullable BlockGetter world, List<Component> tooltip, TooltipFlag flag) {
Auxiliaries.Tooltip.addInformation(stack, world, tooltip, flag, true);
}
@Override
public StandardBlocks.IStandardBlock.RenderTypeHint getRenderTypeHint()
{ return StandardBlocks.IStandardBlock.RenderTypeHint.TRANSLUCENT; }
public StandardBlocks.IStandardBlock.RenderTypeHint getRenderTypeHint() {
return StandardBlocks.IStandardBlock.RenderTypeHint.TRANSLUCENT;
}
@Override
@OnlyIn(Dist.CLIENT)
@SuppressWarnings("deprecation")
public boolean skipRendering(BlockState state, BlockState adjacentBlockState, Direction side)
{ return (adjacentBlockState.getBlock()==this) || (super.skipRendering(state, adjacentBlockState, side)); }
public boolean skipRendering(BlockState state, BlockState adjacentBlockState, Direction side) {
return (adjacentBlockState.getBlock() == this) || (super.skipRendering(state, adjacentBlockState, side));
}
@Override
public boolean isPossibleToRespawnInThis()
{ return false; }
public boolean isPossibleToRespawnInThis(BlockState p_279289_) {
return false;
}
}

View file

@ -8,6 +8,8 @@
*/
package dev.zontreck.engineerdecor.blocks;
import dev.zontreck.libzontreck.edlibmc.Auxiliaries;
import dev.zontreck.libzontreck.edlibmc.StandardBlocks;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.sounds.SoundEvents;
@ -22,6 +24,7 @@ import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.SignalGetter;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState;
@ -35,30 +38,28 @@ import net.minecraft.world.phys.Vec3;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import dev.zontreck.engineerdecor.libmc.StandardBlocks;
import dev.zontreck.engineerdecor.libmc.Auxiliaries;
import javax.annotation.Nullable;
import java.util.List;
public class EdHatchBlock extends StandardBlocks.HorizontalWaterLoggable
{
public class EdHatchBlock extends StandardBlocks.HorizontalWaterLoggable {
public static final BooleanProperty OPEN = BlockStateProperties.OPEN;
public static final BooleanProperty POWERED = BlockStateProperties.POWERED;
protected final List<VoxelShape> vshapes_open;
public EdHatchBlock(long config, BlockBehaviour.Properties builder, final AABB unrotatedAABBClosed, final AABB unrotatedAABBOpen)
{
super(config, builder, unrotatedAABBClosed); vshapes_open = makeHorizontalShapeLookup(new AABB[]{unrotatedAABBOpen});
public EdHatchBlock(long config, BlockBehaviour.Properties builder, final AABB unrotatedAABBClosed, final AABB unrotatedAABBOpen) {
super(config, builder, unrotatedAABBClosed);
vshapes_open = makeHorizontalShapeLookup(new AABB[]{unrotatedAABBOpen});
registerDefaultState(super.defaultBlockState().setValue(OPEN, false).setValue(POWERED, false));
}
public EdHatchBlock(long config, BlockBehaviour.Properties builder, final AABB[] unrotatedAABBsClosed, final AABB[] unrotatedAABBsOpen)
{ super(config, builder, unrotatedAABBsClosed); vshapes_open = makeHorizontalShapeLookup(unrotatedAABBsOpen); }
public EdHatchBlock(long config, BlockBehaviour.Properties builder, final AABB[] unrotatedAABBsClosed, final AABB[] unrotatedAABBsOpen) {
super(config, builder, unrotatedAABBsClosed);
vshapes_open = makeHorizontalShapeLookup(unrotatedAABBsOpen);
}
protected static List<VoxelShape> makeHorizontalShapeLookup(final AABB[] unrotatedAABBs)
{
protected static List<VoxelShape> makeHorizontalShapeLookup(final AABB[] unrotatedAABBs) {
return List.of(
Shapes.block(),
Shapes.block(),
@ -70,29 +71,33 @@ public class EdHatchBlock extends StandardBlocks.HorizontalWaterLoggable
}
@Override
public RenderTypeHint getRenderTypeHint()
{ return RenderTypeHint.CUTOUT; }
public RenderTypeHint getRenderTypeHint() {
return RenderTypeHint.CUTOUT;
}
@Override
public VoxelShape getShape(BlockState state, BlockGetter source, BlockPos pos, CollisionContext selectionContext)
{ return state.getValue(OPEN) ? vshapes_open.get((state.getValue(HORIZONTAL_FACING)).get3DDataValue()) : super.getShape(state, source, pos, selectionContext); }
public VoxelShape getShape(BlockState state, BlockGetter source, BlockPos pos, CollisionContext selectionContext) {
return state.getValue(OPEN) ? vshapes_open.get((state.getValue(HORIZONTAL_FACING)).get3DDataValue()) : super.getShape(state, source, pos, selectionContext);
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockGetter source, BlockPos pos, CollisionContext selectionContext)
{ return getShape(state, source, pos, selectionContext); }
public VoxelShape getCollisionShape(BlockState state, BlockGetter source, BlockPos pos, CollisionContext selectionContext) {
return getShape(state, source, pos, selectionContext);
}
@Override
public boolean propagatesSkylightDown(BlockState state, BlockGetter reader, BlockPos pos)
{ return state.getValue(OPEN); }
public boolean propagatesSkylightDown(BlockState state, BlockGetter reader, BlockPos pos) {
return state.getValue(OPEN);
}
@Override
@SuppressWarnings("deprecation")
public boolean isPathfindable(BlockState state, BlockGetter world, BlockPos pos, PathComputationType type)
{ return !state.getValue(OPEN); }
public boolean isPathfindable(BlockState state, BlockGetter world, BlockPos pos, PathComputationType type) {
return !state.getValue(OPEN);
}
@Override
public boolean isLadder(BlockState state, LevelReader world, BlockPos pos, LivingEntity entity)
{
public boolean isLadder(BlockState state, LevelReader world, BlockPos pos, LivingEntity entity) {
if (!state.getValue(OPEN)) return false;
{
final BlockState up_state = world.getBlockState(pos.above());
@ -108,17 +113,19 @@ public class EdHatchBlock extends StandardBlocks.HorizontalWaterLoggable
}
@Override
public boolean isValidSpawn(BlockState state, BlockGetter world, BlockPos pos, SpawnPlacements.Type type, @Nullable EntityType<?> entityType)
{ return false; }
public boolean isValidSpawn(BlockState state, BlockGetter world, BlockPos pos, SpawnPlacements.Type type, @Nullable EntityType<?> entityType) {
return false;
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder)
{ super.createBlockStateDefinition(builder); builder.add(OPEN, POWERED); }
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
super.createBlockStateDefinition(builder);
builder.add(OPEN, POWERED);
}
@Override
@SuppressWarnings("deprecation")
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult rayTraceResult)
{
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult rayTraceResult) {
if (world.isClientSide()) return InteractionResult.SUCCESS;
boolean open = !state.getValue(OPEN);
world.setBlock(pos, state.setValue(OPEN, open), 1 | 2);
@ -128,12 +135,12 @@ public class EdHatchBlock extends StandardBlocks.HorizontalWaterLoggable
@Override
@SuppressWarnings("deprecation")
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block block, BlockPos fromPos, boolean isMoving)
{
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block block, BlockPos fromPos, boolean isMoving) {
if ((world.isClientSide) || (!(state.getBlock() instanceof EdHatchBlock))) return;
boolean powered = world.hasNeighborSignal(pos);
if (powered == state.getValue(POWERED)) return;
if(powered != state.getValue(OPEN)) world.playSound(null, pos, powered?SoundEvents.IRON_DOOR_OPEN:SoundEvents.IRON_DOOR_CLOSE, SoundSource.BLOCKS, 0.7f, 1.4f);
if (powered != state.getValue(OPEN))
world.playSound(null, pos, powered ? SoundEvents.IRON_DOOR_OPEN : SoundEvents.IRON_DOOR_CLOSE, SoundSource.BLOCKS, 0.7f, 1.4f);
world.setBlock(pos, state.setValue(OPEN, powered).setValue(POWERED, powered), 1 | 2);
}
@ -150,13 +157,13 @@ public class EdHatchBlock extends StandardBlocks.HorizontalWaterLoggable
}
@Override
public boolean shouldCheckWeakPower(BlockState state, LevelReader world, BlockPos pos, Direction side)
{ return false; }
public boolean shouldCheckWeakPower(BlockState state, SignalGetter level, BlockPos pos, Direction side) {
return false;
}
@Override
@SuppressWarnings("deprecation")
public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity)
{
public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
if ((!state.getValue(OPEN)) || (!(entity instanceof final Player player))) return;
if (player.isSteppingCarefully()) return;
if (entity.getLookAngle().y() > -0.75) return;

View file

@ -9,7 +9,9 @@
package dev.zontreck.engineerdecor.blocks;
import com.mojang.blaze3d.vertex.PoseStack;
import dev.zontreck.engineerdecor.libmc.*;
import dev.zontreck.engineerdecor.ModContent;
import dev.zontreck.libzontreck.edlibmc.*;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
@ -27,6 +29,7 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.SignalGetter;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockBehaviour;
@ -42,8 +45,6 @@ import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.capabilities.ForgeCapabilities;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.items.IItemHandler;
import dev.zontreck.engineerdecor.ModContent;
import wile.engineersdecor.libmc.*;
import javax.annotation.Nullable;
import java.util.ArrayList;
@ -51,41 +52,43 @@ import java.util.List;
import java.util.function.Supplier;
public class EdHopper
{
public static void on_config()
{}
public class EdHopper {
public static void on_config() {
}
//--------------------------------------------------------------------------------------------------------------------
// Block
//--------------------------------------------------------------------------------------------------------------------
public static class HopperBlock extends StandardBlocks.Directed implements StandardEntityBlocks.IStandardEntityBlock<EdHopper.HopperTileEntity>
{
public HopperBlock(long config, BlockBehaviour.Properties builder, final Supplier<ArrayList<VoxelShape>> shape_supplier)
{ super(config, builder, shape_supplier); }
public static class HopperBlock extends StandardBlocks.Directed implements StandardEntityBlocks.IStandardEntityBlock<EdHopper.HopperTileEntity> {
public HopperBlock(long config, BlockBehaviour.Properties builder, final Supplier<ArrayList<VoxelShape>> shape_supplier) {
super(config, builder, shape_supplier);
}
@Override
public boolean isBlockEntityTicking(Level world, BlockState state)
{ return true; }
public boolean isBlockEntityTicking(Level world, BlockState state) {
return true;
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context)
{ return Shapes.block(); }
public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) {
return Shapes.block();
}
@Override
@SuppressWarnings("deprecation")
public boolean hasAnalogOutputSignal(BlockState state)
{ return true; }
public boolean hasAnalogOutputSignal(BlockState state) {
return true;
}
@Override
@SuppressWarnings("deprecation")
public int getAnalogOutputSignal(BlockState blockState, Level world, BlockPos pos)
{ return (world.getBlockEntity(pos) instanceof EdHopper.HopperTileEntity te) ? RsSignals.fromContainer(te.storage_slot_range_) : 0; }
public int getAnalogOutputSignal(BlockState blockState, Level world, BlockPos pos) {
return (world.getBlockEntity(pos) instanceof EdHopper.HopperTileEntity te) ? RsSignals.fromContainer(te.storage_slot_range_) : 0;
}
@Override
public void setPlacedBy(Level world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack)
{
public void setPlacedBy(Level world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) {
if (world.isClientSide) return;
if ((!stack.hasTag()) || (!stack.getTag().contains("tedata"))) return;
CompoundTag te_nbt = stack.getTag().getCompound("tedata");
@ -98,12 +101,12 @@ public class EdHopper
}
@Override
public boolean hasDynamicDropList()
{ return true; }
public boolean hasDynamicDropList() {
return true;
}
@Override
public List<ItemStack> dropList(BlockState state, Level world, final BlockEntity te, boolean explosion)
{
public List<ItemStack> dropList(BlockState state, Level world, final BlockEntity te, boolean explosion) {
final List<ItemStack> stacks = new ArrayList<>();
if (world.isClientSide) return stacks;
if (!(te instanceof HopperTileEntity)) return stacks;
@ -127,13 +130,13 @@ public class EdHopper
@Override
@SuppressWarnings("deprecation")
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult rayTraceResult)
{ return useOpenGui(state, world, pos, player); }
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult rayTraceResult) {
return useOpenGui(state, world, pos, player);
}
@Override
@SuppressWarnings("deprecation")
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block block, BlockPos fromPos, boolean unused)
{
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block block, BlockPos fromPos, boolean unused) {
if (!(world instanceof Level) || (world.isClientSide)) return;
BlockEntity te = world.getBlockEntity(pos);
if (!(te instanceof HopperTileEntity)) return;
@ -141,8 +144,7 @@ public class EdHopper
}
@Override
public void fallOn(Level world, BlockState state, BlockPos pos, Entity entity, float fallDistance)
{
public void fallOn(Level world, BlockState state, BlockPos pos, Entity entity, float fallDistance) {
super.fallOn(world, state, pos, entity, fallDistance);
if (!(entity instanceof ItemEntity)) return;
if (!(world.getBlockEntity(pos) instanceof HopperTileEntity te)) return;
@ -150,23 +152,27 @@ public class EdHopper
}
@Override
public boolean shouldCheckWeakPower(BlockState state, LevelReader world, BlockPos pos, Direction side)
{ return false; }
public boolean shouldCheckWeakPower(BlockState state, SignalGetter level, BlockPos pos, Direction side) {
return false;
}
@Override
@SuppressWarnings("deprecation")
public boolean isSignalSource(BlockState state)
{ return true; }
public boolean isSignalSource(BlockState state) {
return true;
}
@Override
@SuppressWarnings("deprecation")
public int getSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side)
{ return 0; }
public int getSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side) {
return 0;
}
@Override
@SuppressWarnings("deprecation")
public int getDirectSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side)
{ return 0; }
public int getDirectSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side) {
return 0;
}
}
@ -174,8 +180,7 @@ public class EdHopper
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
public static class HopperTileEntity extends StandardEntityBlocks.StandardBlockEntity implements MenuProvider, Nameable
{
public static class HopperTileEntity extends StandardEntityBlocks.StandardBlockEntity implements MenuProvider, Nameable {
public static final int NUM_OF_FIELDS = 7;
public static final int TICK_INTERVAL = 10;
public static final int COLLECTION_INTERVAL = 50;
@ -189,6 +194,9 @@ public class EdHopper
public static final int LOGIC_INVERTED = 0x01;
public static final int LOGIC_CONTINUOUS = 0x02;
public static final int LOGIC_IGNORE_EXT = 0x04;
protected final Inventories.StorageInventory main_inventory_ = new Inventories.StorageInventory(this, NUM_OF_SLOTS, 1);
protected final Inventories.InventoryRange storage_slot_range_ = new Inventories.InventoryRange(main_inventory_, 0, NUM_OF_STORAGE_SLOTS);
protected LazyOptional<? extends IItemHandler> item_handler_ = Inventories.MappedItemHandler.createGenericHandler(storage_slot_range_);
///
private boolean block_power_signal_ = false;
private boolean block_power_updated_ = false;
@ -199,25 +207,56 @@ public class EdHopper
private int transfer_period_ = 0;
private int collection_range_ = 0;
private int current_slot_index_ = 0;
private int tick_timer_ = 0;
protected final Inventories.StorageInventory main_inventory_ = new Inventories.StorageInventory(this, NUM_OF_SLOTS, 1);
protected final Inventories.InventoryRange storage_slot_range_ = new Inventories.InventoryRange(main_inventory_, 0, NUM_OF_STORAGE_SLOTS);
protected LazyOptional<? extends IItemHandler> item_handler_ = Inventories.MappedItemHandler.createGenericHandler(storage_slot_range_);
protected final ContainerData fields = new ContainerData() {
@Override
public int getCount() {
return HopperTileEntity.NUM_OF_FIELDS;
}
public HopperTileEntity(BlockPos pos, BlockState state)
{
@Override
public int get(int id) {
return switch (id) {
case 0 -> collection_range_;
case 1 -> transfer_count_;
case 2 -> logic_;
case 3 -> transfer_period_;
case 4 -> delay_timer_;
case 5 -> block_power_signal_ ? 1 : 0;
case 6 -> current_slot_index_;
default -> 0;
};
}
@Override
public void set(int id, int value) {
switch (id) {
case 0 -> collection_range_ = Mth.clamp(value, 0, MAX_COLLECTION_RANGE);
case 1 -> transfer_count_ = Mth.clamp(value, 1, MAX_TRANSFER_COUNT);
case 2 -> logic_ = value;
case 3 -> transfer_period_ = Mth.clamp(value, 0, 100);
case 4 -> delay_timer_ = Mth.clamp(value, 0, 400);
case 5 -> block_power_signal_ = (value != 0);
case 6 -> current_slot_index_ = Mth.clamp(value, 0, NUM_OF_STORAGE_SLOTS - 1);
}
}
};
private int tick_timer_ = 0;
public HopperTileEntity(BlockPos pos, BlockState state) {
super(ModContent.getBlockEntityTypeOfBlock(state.getBlock()), pos, state);
main_inventory_.setSlotChangeAction((slot, stack) -> tick_timer_ = Math.min(tick_timer_, 8));
}
public void reset_rtstate()
{
private static int next_slot(int i) {
return (i < NUM_OF_STORAGE_SLOTS - 1) ? (i + 1) : 0;
}
public void reset_rtstate() {
block_power_signal_ = false;
block_power_updated_ = false;
}
public CompoundTag clear_getnbt()
{
public CompoundTag clear_getnbt() {
CompoundTag nbt = new CompoundTag();
block_power_signal_ = false;
writenbt(nbt, false);
@ -229,8 +268,7 @@ public class EdHopper
return nbt;
}
public void readnbt(CompoundTag nbt, boolean update_packet)
{
public void readnbt(CompoundTag nbt, boolean update_packet) {
main_inventory_.load(nbt);
block_power_signal_ = nbt.getBoolean("powered");
current_slot_index_ = nbt.getInt("act_slot_index");
@ -240,8 +278,9 @@ public class EdHopper
collection_range_ = nbt.getInt("range");
}
protected void writenbt(CompoundTag nbt, boolean update_packet)
{
// BlockEntity --------------------------------------------------------------------------------------------
protected void writenbt(CompoundTag nbt, boolean update_packet) {
main_inventory_.save(nbt);
nbt.putBoolean("powered", block_power_signal_);
nbt.putInt("act_slot_index", current_slot_index_);
@ -251,8 +290,7 @@ public class EdHopper
nbt.putInt("range", collection_range_);
}
public void block_updated()
{
public void block_updated() {
// RS power check, both edges
boolean powered = level.hasNeighborSignal(worldPosition);
if (block_power_signal_ != powered) block_power_updated_ = true;
@ -260,46 +298,42 @@ public class EdHopper
tick_timer_ = 1;
}
// BlockEntity --------------------------------------------------------------------------------------------
@Override
public void load(CompoundTag nbt)
{ super.load(nbt); readnbt(nbt, false); }
@Override
protected void saveAdditional(CompoundTag nbt)
{ super.saveAdditional(nbt); writenbt(nbt, false); }
@Override
public void setRemoved()
{
super.setRemoved();
item_handler_.invalidate();
public void load(CompoundTag nbt) {
super.load(nbt);
readnbt(nbt, false);
}
// Namable ----------------------------------------------------------------------------------------------
@Override
public Component getName()
{ return Auxiliaries.localizable(getBlockState().getBlock().getDescriptionId()); }
protected void saveAdditional(CompoundTag nbt) {
super.saveAdditional(nbt);
writenbt(nbt, false);
}
@Override
public boolean hasCustomName()
{ return false; }
public void setRemoved() {
super.setRemoved();
item_handler_.invalidate();
}
@Override
public Component getCustomName()
{ return getName(); }
public Component getName() {
return Auxiliaries.localizable(getBlockState().getBlock().getDescriptionId());
}
// INamedContainerProvider ------------------------------------------------------------------------------
@Override
public Component getDisplayName()
{ return Nameable.super.getDisplayName(); }
public boolean hasCustomName() {
return false;
}
@Override
public AbstractContainerMenu createMenu(int id, Inventory inventory, Player player )
{ return new HopperContainer(id, inventory, main_inventory_, ContainerLevelAccess.create(level, worldPosition), fields); }
public Component getCustomName() {
return getName();
}
/// CONTAINER SETITEM
// @Override
@ -313,69 +347,41 @@ public class EdHopper
// Fields -----------------------------------------------------------------------------------------------
protected final ContainerData fields = new ContainerData()
{
@Override
public int getCount()
{ return HopperTileEntity.NUM_OF_FIELDS; }
@Override
public int get(int id)
{
return switch(id) {
case 0 -> collection_range_;
case 1 -> transfer_count_;
case 2 -> logic_;
case 3 -> transfer_period_;
case 4 -> delay_timer_;
case 5 -> block_power_signal_ ? 1 : 0;
case 6 -> current_slot_index_;
default -> 0;
};
public Component getDisplayName() {
return Nameable.super.getDisplayName();
}
@Override
public void set(int id, int value)
{
switch (id) {
case 0 -> collection_range_ = Mth.clamp(value, 0, MAX_COLLECTION_RANGE);
case 1 -> transfer_count_ = Mth.clamp(value, 1, MAX_TRANSFER_COUNT);
case 2 -> logic_ = value;
case 3 -> transfer_period_ = Mth.clamp(value, 0, 100);
case 4 -> delay_timer_ = Mth.clamp(value, 0, 400);
case 5 -> block_power_signal_ = (value != 0);
case 6 -> current_slot_index_ = Mth.clamp(value, 0, NUM_OF_STORAGE_SLOTS - 1);
}
}
};
// Capability export ------------------------------------------------------------------------------------
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if(capability == ForgeCapabilities.ITEM_HANDLER) return item_handler_.cast();
return super.getCapability(capability, facing);
public AbstractContainerMenu createMenu(int id, Inventory inventory, Player player) {
return new HopperContainer(id, inventory, main_inventory_, ContainerLevelAccess.create(level, worldPosition), fields);
}
// ITickable and aux methods ---------------------------------------------------------------------
private IItemHandler inventory_entity_handler(BlockPos where)
{
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing) {
if (capability == ForgeCapabilities.ITEM_HANDLER) return item_handler_.cast();
return super.getCapability(capability, facing);
}
private IItemHandler inventory_entity_handler(BlockPos where) {
final List<Entity> entities = level.getEntities((Entity) null, (new AABB(where)), EntitySelector.CONTAINER_ENTITY_SELECTOR);
return entities.isEmpty() ? null : Inventories.itemhandler(entities.get(0));
}
private static int next_slot(int i)
{ return (i<NUM_OF_STORAGE_SLOTS-1) ? (i+1) : 0; }
private int try_insert_into_hopper(final ItemStack stack)
{
private int try_insert_into_hopper(final ItemStack stack) {
final int max_to_insert = stack.getCount();
int n_to_insert = max_to_insert;
int first_empty_slot = -1;
for (int i = 0; i < storage_slot_range_.size(); ++i) {
final ItemStack slotstack = storage_slot_range_.get(i);
if((first_empty_slot < 0) && slotstack.isEmpty()) { first_empty_slot=i; continue; }
if ((first_empty_slot < 0) && slotstack.isEmpty()) {
first_empty_slot = i;
continue;
}
if (Inventories.areItemStacksDifferent(stack, slotstack)) continue;
int nspace = slotstack.getMaxStackSize() - slotstack.getCount();
if (nspace <= 0) {
@ -398,8 +404,7 @@ public class EdHopper
return max_to_insert - n_to_insert;
}
private boolean try_insert(Direction facing)
{
private boolean try_insert(Direction facing) {
ItemStack current_stack = ItemStack.EMPTY;
for (int i = 0; i < NUM_OF_STORAGE_SLOTS; ++i) {
if (current_slot_index_ >= NUM_OF_STORAGE_SLOTS) current_slot_index_ = 0;
@ -418,7 +423,10 @@ public class EdHopper
final BlockEntity te = level.getBlockEntity(facing_pos);
if (te != null) {
ih = te.getCapability(ForgeCapabilities.ITEM_HANDLER, facing.getOpposite()).orElse(null);
if(ih == null) { delay_timer_ = TICK_INTERVAL+2; return false; }
if (ih == null) {
delay_timer_ = TICK_INTERVAL + 2;
return false;
}
if (te instanceof net.minecraft.world.level.block.entity.HopperBlockEntity) {
Direction f = level.getBlockState(facing_pos).getValue(net.minecraft.world.level.block.HopperBlock.FACING);
if (f == facing.getOpposite()) return false; // no back transfer
@ -430,7 +438,10 @@ public class EdHopper
}
// Entity insertion check
if (ih == null) ih = inventory_entity_handler(facing_pos);
if(ih == null) { delay_timer_ = TICK_INTERVAL+2; return false; } // no reason to recalculate this all the time if there is nowhere to insert.
if (ih == null) {
delay_timer_ = TICK_INTERVAL + 2;
return false;
} // no reason to recalculate this all the time if there is nowhere to insert.
// Handler insertion
{
ItemStack insert_stack = current_stack.copy();
@ -461,8 +472,7 @@ public class EdHopper
}
}
private boolean try_item_handler_extract(final IItemHandler ih)
{
private boolean try_item_handler_extract(final IItemHandler ih) {
final int end = ih.getSlots();
int n_to_extract = transfer_count_;
for (int i = 0; i < end; ++i) {
@ -479,8 +489,7 @@ public class EdHopper
return (n_to_extract < transfer_count_);
}
private boolean try_inventory_extract(final Container inv)
{
private boolean try_inventory_extract(final Container inv) {
final int end = inv.getContainerSize();
int n_to_extract = transfer_count_;
for (int i = 0; i < end; ++i) {
@ -503,8 +512,7 @@ public class EdHopper
}
}
private boolean try_collect(Direction facing)
{
private boolean try_collect(Direction facing) {
AABB collection_volume;
Vec3 rpos;
if (facing == Direction.UP) {
@ -514,7 +522,7 @@ public class EdHopper
rpos = new Vec3(0.5 + worldPosition.getX(), -1.5 + worldPosition.getY(), 0.5 + worldPosition.getZ());
collection_volume = (new AABB(worldPosition.below(2))).inflate(0.1 + collection_range_, 1, 0.1 + collection_range_);
}
final List<ItemEntity> items = level.getEntitiesOfClass(ItemEntity.class, collection_volume, e->(e.isAlive() && e.isOnGround()));
final List<ItemEntity> items = level.getEntitiesOfClass(ItemEntity.class, collection_volume, e -> (e.isAlive() && e.onGround()));
if (items.size() <= 0) return false;
final int max_to_collect = 3;
int n_collected = 0;
@ -539,8 +547,7 @@ public class EdHopper
}
@Override
public void tick()
{
public void tick() {
// Tick cycle pre-conditions
if (level.isClientSide) return;
if ((delay_timer_ > 0) && ((--delay_timer_) == 0)) setChanged();
@ -552,7 +559,10 @@ public class EdHopper
final boolean pulse_mode = ((logic_ & (LOGIC_CONTINUOUS | LOGIC_IGNORE_EXT)) == 0);
boolean trigger = ((logic_ & LOGIC_IGNORE_EXT) != 0) || (rssignal && ((block_power_updated_) || (!pulse_mode)));
final BlockState state = level.getBlockState(worldPosition);
if(!(state.getBlock() instanceof HopperBlock)) { block_power_signal_= false; return; }
if (!(state.getBlock() instanceof HopperBlock)) {
block_power_signal_ = false;
return;
}
final Direction hopper_facing = state.getValue(HopperBlock.FACING);
// Trigger edge detection for next cycle
{
@ -598,15 +608,14 @@ public class EdHopper
// Container
//--------------------------------------------------------------------------------------------------------------------
public static class HopperContainer extends AbstractContainerMenu implements Networking.INetworkSynchronisableContainer
{
public static class HopperContainer extends AbstractContainerMenu implements Networking.INetworkSynchronisableContainer {
protected static final String QUICK_MOVE_ALL = "quick-move-all";
private static final int PLAYER_INV_START_SLOTNO = HopperTileEntity.NUM_OF_SLOTS;
private static final int NUM_OF_CONTAINER_SLOTS = HopperTileEntity.NUM_OF_SLOTS + 36;
protected static final int STORAGE_SLOT_BEGIN = 0;
protected static final int STORAGE_SLOT_END = HopperTileEntity.NUM_OF_SLOTS;
protected static final int PLAYER_SLOT_BEGIN = HopperTileEntity.NUM_OF_SLOTS;
protected static final int PLAYER_SLOT_END = HopperTileEntity.NUM_OF_SLOTS + 36;
private static final int PLAYER_INV_START_SLOTNO = HopperTileEntity.NUM_OF_SLOTS;
private static final int NUM_OF_CONTAINER_SLOTS = HopperTileEntity.NUM_OF_SLOTS + 36;
private final Inventories.InventoryRange player_inventory_range_;
private final Inventories.InventoryRange block_storage_range_;
private final Player player_;
@ -614,13 +623,11 @@ public class EdHopper
private final ContainerLevelAccess wpc_;
private final ContainerData fields_;
public final int field(int index) { return fields_.get(index); }
public HopperContainer(int cid, Inventory player_inventory) {
this(cid, player_inventory, new SimpleContainer(HopperTileEntity.NUM_OF_SLOTS), ContainerLevelAccess.NULL, new SimpleContainerData(HopperTileEntity.NUM_OF_FIELDS));
}
public HopperContainer(int cid, Inventory player_inventory)
{ this(cid, player_inventory, new SimpleContainer(HopperTileEntity.NUM_OF_SLOTS), ContainerLevelAccess.NULL, new SimpleContainerData(HopperTileEntity.NUM_OF_FIELDS)); }
private HopperContainer(int cid, Inventory player_inventory, Container block_inventory, ContainerLevelAccess wpc, ContainerData fields)
{
private HopperContainer(int cid, Inventory player_inventory, Container block_inventory, ContainerLevelAccess wpc, ContainerData fields) {
super(ModContent.getMenuType("factory_hopper"), cid); // @todo: class mapping
fields_ = fields;
wpc_ = wpc;
@ -648,20 +655,25 @@ public class EdHopper
this.addDataSlots(fields_); // === Add reference holders
}
@Override
public boolean stillValid(Player player)
{ return inventory_.stillValid(player); }
public final int field(int index) {
return fields_.get(index);
}
@Override
public ItemStack quickMoveStack(Player player, int index)
{
public boolean stillValid(Player player) {
return inventory_.stillValid(player);
}
@Override
public ItemStack quickMoveStack(Player player, int index) {
Slot slot = getSlot(index);
if ((slot == null) || (!slot.hasItem())) return ItemStack.EMPTY;
ItemStack slot_stack = slot.getItem();
ItemStack transferred = slot_stack.copy();
if ((index >= 0) && (index < PLAYER_INV_START_SLOTNO)) {
// Device slots
if(!moveItemStackTo(slot_stack, PLAYER_INV_START_SLOTNO, PLAYER_INV_START_SLOTNO+36, false)) return ItemStack.EMPTY;
if (!moveItemStackTo(slot_stack, PLAYER_INV_START_SLOTNO, PLAYER_INV_START_SLOTNO + 36, false))
return ItemStack.EMPTY;
} else if ((index >= PLAYER_INV_START_SLOTNO) && (index <= PLAYER_INV_START_SLOTNO + 36)) {
// Player slot
if (!moveItemStackTo(slot_stack, 0, HopperTileEntity.NUM_OF_SLOTS, false)) return ItemStack.EMPTY;
@ -682,38 +694,43 @@ public class EdHopper
// INetworkSynchronisableContainer ---------------------------------------------------------
@OnlyIn(Dist.CLIENT)
public void onGuiAction(CompoundTag nbt)
{ Networking.PacketContainerSyncClientToServer.sendToServer(containerId, nbt); }
public void onGuiAction(CompoundTag nbt) {
Networking.PacketContainerSyncClientToServer.sendToServer(containerId, nbt);
}
@OnlyIn(Dist.CLIENT)
public void onGuiAction(String key, int value)
{
public void onGuiAction(String key, int value) {
CompoundTag nbt = new CompoundTag();
nbt.putInt(key, value);
Networking.PacketContainerSyncClientToServer.sendToServer(containerId, nbt);
}
@OnlyIn(Dist.CLIENT)
public void onGuiAction(String message, CompoundTag nbt)
{
public void onGuiAction(String message, CompoundTag nbt) {
nbt.putString("action", message);
Networking.PacketContainerSyncClientToServer.sendToServer(containerId, nbt);
}
@Override
public void onServerPacketReceived(int windowId, CompoundTag nbt)
{}
public void onServerPacketReceived(int windowId, CompoundTag nbt) {
}
@Override
public void onClientPacketReceived(int windowId, Player player, CompoundTag nbt)
{
public void onClientPacketReceived(int windowId, Player player, CompoundTag nbt) {
if (!(inventory_ instanceof Inventories.StorageInventory)) return;
if(!((((((Inventories.StorageInventory)inventory_).getBlockEntity())) instanceof final EdHopper.HopperTileEntity te))) return;
if(nbt.contains("xsize")) te.transfer_count_ = Mth.clamp(nbt.getInt("xsize"), 1, HopperTileEntity.MAX_TRANSFER_COUNT);
if (!((((((Inventories.StorageInventory) inventory_).getBlockEntity())) instanceof final EdHopper.HopperTileEntity te)))
return;
if (nbt.contains("xsize"))
te.transfer_count_ = Mth.clamp(nbt.getInt("xsize"), 1, HopperTileEntity.MAX_TRANSFER_COUNT);
if (nbt.contains("period")) te.transfer_period_ = Mth.clamp(nbt.getInt("period"), 0, 100);
if(nbt.contains("range")) te.collection_range_ = Mth.clamp(nbt.getInt("range"), 0, HopperTileEntity.MAX_COLLECTION_RANGE);
if (nbt.contains("range"))
te.collection_range_ = Mth.clamp(nbt.getInt("range"), 0, HopperTileEntity.MAX_COLLECTION_RANGE);
if (nbt.contains("logic")) te.logic_ = nbt.getInt("logic");
if(nbt.contains("manual_trigger") && (nbt.getInt("manual_trigger")!=0)) { te.block_power_signal_=true; te.block_power_updated_=true; te.tick_timer_=1; }
if (nbt.contains("manual_trigger") && (nbt.getInt("manual_trigger") != 0)) {
te.block_power_signal_ = true;
te.block_power_updated_ = true;
te.tick_timer_ = 1;
}
if (nbt.contains("action")) {
boolean changed = false;
final int slotId = nbt.contains("slot") ? nbt.getInt("slot") : -1;
@ -741,14 +758,13 @@ public class EdHopper
//--------------------------------------------------------------------------------------------------------------------
@OnlyIn(Dist.CLIENT)
public static class HopperGui extends Guis.ContainerGui<HopperContainer>
{
public HopperGui(HopperContainer container, Inventory player_inventory, Component title)
{ super(container, player_inventory, title, "textures/gui/factory_hopper_gui.png"); }
public static class HopperGui extends Guis.ContainerGui<HopperContainer> {
public HopperGui(HopperContainer container, Inventory player_inventory, Component title) {
super(container, player_inventory, title, "textures/gui/factory_hopper_gui.png");
}
@Override
public void init()
{
public void init() {
super.init();
{
final Block block = ModContent.getBlock(Auxiliaries.getResourceLocation(getMenu().getType()).getPath().replaceAll("^ct_", ""));
@ -767,8 +783,7 @@ public class EdHopper
}
@Override
protected void renderBgWidgets(PoseStack mx, float partialTicks, int mouseX, int mouseY)
{
protected void renderBgWidgets(GuiGraphics mx, float partialTicks, int mouseX, int mouseY) {
final int x0 = getGuiLeft(), y0 = getGuiTop(), w = getXSize(), h = getYSize();
HopperContainer container = getMenu();
// active slot
@ -777,7 +792,7 @@ public class EdHopper
if ((slot_index < 0) || (slot_index >= HopperTileEntity.NUM_OF_SLOTS)) slot_index = 0;
int x = (x0 + 10 + ((slot_index % 6) * 18));
int y = (y0 + 8 + ((slot_index / 6) * 17));
blit(mx, x, y, 200, 8, 18, 18);
mx.blit(getBackgroundImage(), x, y, 200, 8, 18, 18);
}
// collection range
{
@ -785,46 +800,45 @@ public class EdHopper
int px = lut[Mth.clamp(container.field(0), 0, HopperTileEntity.MAX_COLLECTION_RANGE)];
int x = x0 + px - 2;
int y = y0 + 14;
blit(mx, x, y, 179, 40, 5, 5);
mx.blit(getBackgroundImage(), x, y, 179, 40, 5, 5);
}
// transfer period
{
int px = (int) Math.round(((33.5 * container.field(3)) / 100) + 1);
int x = x0 + 132 - 2 + Mth.clamp(px, 0, 34);
int y = y0 + 27;
blit(mx, x, y, 179, 40, 5, 5);
mx.blit(getBackgroundImage(), x, y, 179, 40, 5, 5);
}
// transfer count
{
int x = x0 + 133 - 2 + (container.field(1));
int y = y0 + 40;
blit(mx, x, y, 179, 40, 5, 5);
mx.blit(getBackgroundImage(), x, y, 179, 40, 5, 5);
}
// redstone input
{
if (container.field(5) != 0) {
blit(mx, x0+133, y0+49, 217, 49, 9, 9);
mx.blit(getBackgroundImage(), x0 + 133, y0 + 49, 217, 49, 9, 9);
}
}
// trigger logic
{
int inverter_offset_x = ((container.field(2) & HopperTileEntity.LOGIC_INVERTED) != 0) ? 11 : 0;
int inverter_offset_y = ((container.field(2) & HopperTileEntity.LOGIC_IGNORE_EXT) != 0) ? 10 : 0;
blit(mx, x0+145, y0+49, 177+inverter_offset_x, 49+inverter_offset_y, 9, 9);
mx.blit(getBackgroundImage(), x0 + 145, y0 + 49, 177 + inverter_offset_x, 49 + inverter_offset_y, 9, 9);
int pulse_mode_offset = ((container.field(2) & HopperTileEntity.LOGIC_CONTINUOUS) != 0) ? 9 : 0;
blit(mx, x0+159, y0+49, 199+pulse_mode_offset, 49, 9, 9);
mx.blit(getBackgroundImage(), x0 + 159, y0 + 49, 199 + pulse_mode_offset, 49, 9, 9);
}
// delay timer running indicator
{
if ((container.field(4) > HopperTileEntity.PERIOD_OFFSET) && ((System.currentTimeMillis() % 1000) < 500)) {
blit(mx, x0+148, y0+22, 187, 22, 3, 3);
mx.blit(getBackgroundImage(), x0 + 148, y0 + 22, 187, 22, 3, 3);
}
}
}
@Override
protected void slotClicked(Slot slot, int slotId, int button, ClickType type)
{
protected void slotClicked(Slot slot, int slotId, int button, ClickType type) {
tooltip_.resetTimer();
if ((type == ClickType.QUICK_MOVE) && (slot != null) && slot.hasItem() && Auxiliaries.isShiftDown() && Auxiliaries.isCtrlDown()) {
CompoundTag nbt = new CompoundTag();
@ -836,8 +850,7 @@ public class EdHopper
}
@Override
public boolean mouseClicked(double mouseX, double mouseY, int mouseButton)
{
public boolean mouseClicked(double mouseX, double mouseY, int mouseButton) {
tooltip_.resetTimer();
HopperContainer container = getMenu();
int mx = (int) (mouseX - getGuiLeft() + .5), my = (int) (mouseY - getGuiTop() + .5);

View file

@ -9,6 +9,9 @@
*/
package dev.zontreck.engineerdecor.blocks;
import dev.zontreck.libzontreck.edlibmc.Auxiliaries;
import dev.zontreck.libzontreck.edlibmc.Inventories;
import dev.zontreck.libzontreck.edlibmc.StandardBlocks;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.sounds.SoundEvents;
@ -39,9 +42,6 @@ import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
import dev.zontreck.engineerdecor.ModContent;
import dev.zontreck.engineerdecor.libmc.StandardBlocks;
import dev.zontreck.engineerdecor.libmc.Auxiliaries;
import dev.zontreck.engineerdecor.libmc.Inventories;
import javax.annotation.Nullable;
import java.util.HashMap;
@ -85,8 +85,9 @@ public class EdHorizontalSupportBlock extends StandardBlocks.WaterLoggable
{ return RenderTypeHint.CUTOUT; }
@Override
public boolean isPossibleToRespawnInThis()
{ return false; }
public boolean isPossibleToRespawnInThis(BlockState p_279289_) {
return false;
}
@Override
public boolean isValidSpawn(BlockState state, BlockGetter world, BlockPos pos, SpawnPlacements.Type type, @Nullable EntityType<?> entityType)

View file

@ -12,6 +12,9 @@
*/
package dev.zontreck.engineerdecor.blocks;
import dev.zontreck.engineerdecor.ModConfig;
import dev.zontreck.libzontreck.edlibmc.Auxiliaries;
import dev.zontreck.libzontreck.edlibmc.StandardBlocks;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.network.chat.Component;
@ -34,16 +37,12 @@ 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 dev.zontreck.engineerdecor.ModConfig;
import dev.zontreck.engineerdecor.libmc.StandardBlocks;
import dev.zontreck.engineerdecor.libmc.Auxiliaries;
import javax.annotation.Nullable;
import java.util.List;
public class EdLadderBlock extends LadderBlock implements StandardBlocks.IStandardBlock
{
public class EdLadderBlock extends LadderBlock implements StandardBlocks.IStandardBlock {
protected static final AABB EDLADDER_UNROTATED_AABB = Auxiliaries.getPixeledAABB(3, 0, 0, 13, 16, 3);
protected static final VoxelShape EDLADDER_SOUTH_AABB = Shapes.create(Auxiliaries.getRotatedAABB(EDLADDER_UNROTATED_AABB, Direction.SOUTH, false));
protected static final VoxelShape EDLADDER_EAST_AABB = Shapes.create(Auxiliaries.getRotatedAABB(EDLADDER_UNROTATED_AABB, Direction.EAST, false));
@ -51,61 +50,26 @@ public class EdLadderBlock extends LadderBlock implements StandardBlocks.IStanda
protected static final VoxelShape EDLADDER_NORTH_AABB = Shapes.create(Auxiliaries.getRotatedAABB(EDLADDER_UNROTATED_AABB, Direction.NORTH, false));
private static boolean without_speed_boost_ = false;
public static void on_config(boolean without_speed_boost)
{
public EdLadderBlock(long config, BlockBehaviour.Properties builder) {
super(builder);
}
public static void on_config(boolean without_speed_boost) {
without_speed_boost_ = without_speed_boost;
ModConfig.log("Config ladder: without-speed-boost:" + without_speed_boost_);
}
public EdLadderBlock(long config, BlockBehaviour.Properties builder)
{ super(builder); }
@Override
public RenderTypeHint getRenderTypeHint()
{ return RenderTypeHint.CUTOUT; }
@Override
@OnlyIn(Dist.CLIENT)
public void appendHoverText(ItemStack stack, @Nullable BlockGetter world, List<Component> tooltip, TooltipFlag flag)
{ Auxiliaries.Tooltip.addInformation(stack, world, tooltip, flag, true); }
public VoxelShape getShape(BlockState state, BlockGetter worldIn, BlockPos pos)
{
return switch(state.getValue(FACING)) {
case NORTH -> EDLADDER_NORTH_AABB;
case SOUTH -> EDLADDER_SOUTH_AABB;
case WEST -> EDLADDER_WEST_AABB;
default -> EDLADDER_EAST_AABB;
};
}
@Override
public boolean isPossibleToRespawnInThis()
{ return false; }
@Override
public boolean isValidSpawn(BlockState state, BlockGetter world, BlockPos pos, SpawnPlacements.Type type, @Nullable EntityType<?> entityType)
{ return false; }
@Override
@SuppressWarnings("deprecation")
public PushReaction getPistonPushReaction(BlockState state)
{ return PushReaction.NORMAL; }
@Override
public boolean isLadder(BlockState state, LevelReader world, BlockPos pos, LivingEntity entity)
{ return true; }
// Player update event, forwarded from the main mod instance.
public static void onPlayerUpdateEvent(final Player player)
{
if((without_speed_boost_) || (player.isOnGround()) || (!player.onClimbable()) || (player.isSteppingCarefully()) || (player.isSpectator())) return;
public static void onPlayerUpdateEvent(final Player player) {
if ((without_speed_boost_) || (player.onGround()) || (!player.onClimbable()) || (player.isSteppingCarefully()) || (player.isSpectator()))
return;
double lvy = player.getLookAngle().y;
if (Math.abs(lvy) < 0.92) return;
final BlockPos pos = player.blockPosition();
final BlockState state = player.getLevel().getBlockState(pos);
final BlockState state = player.level().getBlockState(pos);
final Block block = state.getBlock();
if(!(block instanceof EdLadderBlock || block instanceof EdHatchBlock && state.getValue(EdHatchBlock.OPEN))) return;
if (!(block instanceof EdLadderBlock || block instanceof EdHatchBlock && state.getValue(EdHatchBlock.OPEN)))
return;
player.resetFallDistance();
if ((player.getDeltaMovement().y() < 0) == (player.getLookAngle().y < 0)) {
player.makeStuckInBlock(state, new Vec3(0.2, (lvy > 0) ? (3) : (6), 0.2));
@ -120,4 +84,45 @@ public class EdLadderBlock extends LadderBlock implements StandardBlocks.IStanda
}
}
@Override
public RenderTypeHint getRenderTypeHint() {
return RenderTypeHint.CUTOUT;
}
@Override
@OnlyIn(Dist.CLIENT)
public void appendHoverText(ItemStack stack, @Nullable BlockGetter world, List<Component> tooltip, TooltipFlag flag) {
Auxiliaries.Tooltip.addInformation(stack, world, tooltip, flag, true);
}
public VoxelShape getShape(BlockState state, BlockGetter worldIn, BlockPos pos) {
return switch (state.getValue(FACING)) {
case NORTH -> EDLADDER_NORTH_AABB;
case SOUTH -> EDLADDER_SOUTH_AABB;
case WEST -> EDLADDER_WEST_AABB;
default -> EDLADDER_EAST_AABB;
};
}
@Override
public boolean isPossibleToRespawnInThis(BlockState p_279289_) {
return false;
}
@Override
public boolean isValidSpawn(BlockState state, BlockGetter world, BlockPos pos, SpawnPlacements.Type type, @Nullable EntityType<?> entityType) {
return false;
}
@Override
@SuppressWarnings("deprecation")
public PushReaction getPistonPushReaction(BlockState state) {
return PushReaction.NORMAL;
}
@Override
public boolean isLadder(BlockState state, LevelReader world, BlockPos pos, LivingEntity entity) {
return true;
}
}

View file

@ -8,7 +8,10 @@
*/
package dev.zontreck.engineerdecor.blocks;
import dev.zontreck.engineerdecor.libmc.*;
import dev.zontreck.engineerdecor.ModConfig;
import dev.zontreck.engineerdecor.ModContent;
import dev.zontreck.libzontreck.edlibmc.*;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
@ -30,6 +33,7 @@ import net.minecraft.world.item.Items;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.SignalGetter;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockBehaviour;
@ -50,9 +54,6 @@ import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
import net.minecraftforge.registries.ForgeRegistries;
import dev.zontreck.engineerdecor.ModConfig;
import dev.zontreck.engineerdecor.ModContent;
import wile.engineersdecor.libmc.*;
import javax.annotation.Nullable;
import java.util.HashMap;
@ -62,8 +63,7 @@ import java.util.Map.Entry;
import java.util.UUID;
public class EdMilker
{
public class EdMilker {
public static final int BUCKET_SIZE = 1000;
public static final int TICK_INTERVAL = 80;
public static final int PROCESSING_TICK_INTERVAL = 20;
@ -75,14 +75,12 @@ public class EdMilker
public static final int DEFAULT_ENERGY_CONSUMPTION = 0;
public static final int DEFAULT_MILKING_DELAY_PER_COW = 4000;
private static final FluidStack NO_MILK_FLUID = new FluidStack(Fluids.WATER, 1000);
private static FluidStack milk_fluid_ = NO_MILK_FLUID;
private static final HashMap<ItemStack, ItemStack> milk_containers_ = new HashMap<>();
private static FluidStack milk_fluid_ = NO_MILK_FLUID;
private static int energy_consumption_ = DEFAULT_ENERGY_CONSUMPTION;
private static long min_milking_delay_per_cow_ticks_ = DEFAULT_MILKING_DELAY_PER_COW;
public static void on_config(int energy_consumption_per_tick, int min_milking_delay_per_cow)
{
public static void on_config(int energy_consumption_per_tick, int min_milking_delay_per_cow) {
energy_consumption_ = Mth.clamp(energy_consumption_per_tick, 0, 1024);
min_milking_delay_per_cow_ticks_ = Mth.clamp(min_milking_delay_per_cow, 1000, 24000);
{
@ -105,51 +103,54 @@ public class EdMilker
// Block
//--------------------------------------------------------------------------------------------------------------------
public static class MilkerBlock extends StandardBlocks.Horizontal implements StandardEntityBlocks.IStandardEntityBlock<MilkerTileEntity>
{
public static class MilkerBlock extends StandardBlocks.Horizontal implements StandardEntityBlocks.IStandardEntityBlock<MilkerTileEntity> {
public static final BooleanProperty FILLED = BooleanProperty.create("filled");
public static final BooleanProperty ACTIVE = BooleanProperty.create("active");
public MilkerBlock(long config, BlockBehaviour.Properties builder, final AABB[] unrotatedAABBs)
{
public MilkerBlock(long config, BlockBehaviour.Properties builder, final AABB[] unrotatedAABBs) {
super(config, builder, unrotatedAABBs);
cshapes.replaceAll((state, shape) -> Shapes.create(Auxiliaries.getPixeledAABB(0, 0, 0, 16, 24, 16)));
}
@Override
public boolean isBlockEntityTicking(Level world, BlockState state)
{ return true; }
public boolean isBlockEntityTicking(Level world, BlockState state) {
return true;
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder)
{ super.createBlockStateDefinition(builder); builder.add(ACTIVE); builder.add(FILLED); }
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
super.createBlockStateDefinition(builder);
builder.add(ACTIVE);
builder.add(FILLED);
}
@Override
@Nullable
public BlockState getStateForPlacement(BlockPlaceContext context)
{ return super.getStateForPlacement(context).setValue(FILLED, false).setValue(ACTIVE, false); }
public BlockState getStateForPlacement(BlockPlaceContext context) {
return super.getStateForPlacement(context).setValue(FILLED, false).setValue(ACTIVE, false);
}
@Override
@SuppressWarnings("deprecation")
public boolean hasAnalogOutputSignal(BlockState state)
{ return true; }
public boolean hasAnalogOutputSignal(BlockState state) {
return true;
}
@Override
@SuppressWarnings("deprecation")
public int getAnalogOutputSignal(BlockState state, Level world, BlockPos pos)
{
public int getAnalogOutputSignal(BlockState state, Level world, BlockPos pos) {
MilkerTileEntity te = getTe(world, pos);
return (te == null) ? 0 : Mth.clamp((16 * te.fluid_level()) / TANK_CAPACITY, 0, 15);
}
@Override
public boolean shouldCheckWeakPower(BlockState state, LevelReader world, BlockPos pos, Direction side)
{ return false; }
public boolean shouldCheckWeakPower(BlockState state, SignalGetter level, BlockPos pos, Direction side) {
return false;
}
@Override
@SuppressWarnings("deprecation")
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit)
{
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
if (world.isClientSide()) return InteractionResult.SUCCESS;
MilkerTileEntity te = getTe(world, pos);
if (te == null) return InteractionResult.FAIL;
@ -186,8 +187,10 @@ public class EdMilker
}
@Nullable
private MilkerTileEntity getTe(Level world, BlockPos pos)
{ final BlockEntity te=world.getBlockEntity(pos); return (!(te instanceof MilkerTileEntity)) ? (null) : ((MilkerTileEntity)te); }
private MilkerTileEntity getTe(Level world, BlockPos pos) {
final BlockEntity te = world.getBlockEntity(pos);
return (!(te instanceof MilkerTileEntity)) ? (null) : ((MilkerTileEntity) te);
}
}
//--------------------------------------------------------------------------------------------------------------------
@ -197,21 +200,19 @@ public class EdMilker
public static class MilkerTileEntity extends StandardEntityBlocks.StandardBlockEntity // implements IFluidTank
{
private static final Direction[] FLUID_TRANSFER_DIRECTRIONS = {Direction.DOWN, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.NORTH};
private enum MilkingState { IDLE, PICKED, COMING, POSITIONING, MILKING, LEAVING, WAITING }
private static final HashMap<Integer, Long> tracked_cows_ = new HashMap<>();
private final RfEnergy.Battery battery_;
private final LazyOptional<IEnergyStorage> energy_handler_;
private final Fluidics.Tank tank_;
private final LazyOptional<IFluidHandler> fluid_handler_;
private int tick_timer_;
private UUID tracked_cow_ = null;
private MilkingState state_ = MilkingState.IDLE;
private int state_timeout_ = 0;
private int state_timer_ = 0;
private BlockPos tracked_cow_original_position_ = null;
private final RfEnergy.Battery battery_;
private final LazyOptional<IEnergyStorage> energy_handler_;
private final Fluidics.Tank tank_;
private final LazyOptional<IFluidHandler> fluid_handler_;
public MilkerTileEntity(BlockPos pos, BlockState state)
{
public MilkerTileEntity(BlockPos pos, BlockState state) {
super(ModContent.getBlockEntityTypeOfBlock(state.getBlock()), pos, state);
tank_ = new Fluidics.Tank(TANK_CAPACITY, 0, BUCKET_SIZE, fs -> fs.isFluidEqual(milk_fluid_));
fluid_handler_ = tank_.createOutputFluidHandler();
@ -220,8 +221,11 @@ public class EdMilker
reset();
}
public void reset()
{
private static ItemStack milk_filled_container_item(ItemStack stack) {
return milk_containers_.entrySet().stream().filter(e -> Inventories.areItemStacksIdentical(e.getKey(), stack)).map(Map.Entry::getValue).findFirst().orElse(ItemStack.EMPTY);
}
public void reset() {
tank_.clear();
battery_.clear();
tick_timer_ = 0;
@ -230,90 +234,91 @@ public class EdMilker
state_timeout_ = 0;
}
public CompoundTag destroy_getnbt()
{
public CompoundTag destroy_getnbt() {
final UUID cowuid = tracked_cow_;
CompoundTag nbt = new CompoundTag();
writenbt(nbt, false); reset();
writenbt(nbt, false);
reset();
if (cowuid == null) return nbt;
level.getEntitiesOfClass(Cow.class, new AABB(worldPosition).inflate(16, 16, 16), e -> e.getUUID().equals(cowuid)).forEach(e -> e.setNoAi(false));
return nbt;
}
public void readnbt(CompoundTag nbt, boolean update_packet)
{
public void readnbt(CompoundTag nbt, boolean update_packet) {
battery_.load(nbt);
tank_.load(nbt);
}
protected void writenbt(CompoundTag nbt, boolean update_packet)
{
protected void writenbt(CompoundTag nbt, boolean update_packet) {
tank_.save(nbt);
if (!battery_.isEmpty()) battery_.save(nbt);
}
private boolean has_milk_fluid()
{ return !(NO_MILK_FLUID.isFluidEqual(milk_fluid_)); }
private boolean has_milk_fluid() {
return !(NO_MILK_FLUID.isFluidEqual(milk_fluid_));
}
private IFluidHandler fluid_handler()
{ return fluid_handler_.orElse(null); }
private IFluidHandler fluid_handler() {
return fluid_handler_.orElse(null);
}
private int fluid_level()
{ return tank_.getFluidAmount(); }
private int fluid_level() {
return tank_.getFluidAmount();
}
private FluidStack drain(int amount)
{ return tank_.drain(amount); }
public void state_message(Player player)
{
Component rf = (energy_consumption_ <= 0) ? (Component.empty()) : (Auxiliaries.localizable("block.engineersdecor.small_milking_machine.status.rf", battery_.getEnergyStored()));
Overlay.show(player, Auxiliaries.localizable("block.engineersdecor.small_milking_machine.status", tank_.getFluidAmount(), rf));
private FluidStack drain(int amount) {
return tank_.drain(amount);
}
// BlockEntity ------------------------------------------------------------------------------
@Override
public void load(CompoundTag nbt)
{ super.load(nbt); readnbt(nbt, false); }
public void state_message(Player player) {
Component rf = (energy_consumption_ <= 0) ? (Component.empty()) : (Auxiliaries.localizable("block.engineersdecor.small_milking_machine.status.rf", battery_.getEnergyStored()));
Overlay.show(player, Auxiliaries.localizable("block.engineersdecor.small_milking_machine.status", tank_.getFluidAmount(), rf));
}
@Override
protected void saveAdditional(CompoundTag nbt)
{ super.saveAdditional(nbt); writenbt(nbt, false); }
public void load(CompoundTag nbt) {
super.load(nbt);
readnbt(nbt, false);
}
@Override
public void setRemoved()
{
super.setRemoved();
energy_handler_.invalidate();
fluid_handler_.invalidate();
protected void saveAdditional(CompoundTag nbt) {
super.saveAdditional(nbt);
writenbt(nbt, false);
}
// ICapabilityProvider ---------------------------------------------------------------------------
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
public void setRemoved() {
super.setRemoved();
energy_handler_.invalidate();
fluid_handler_.invalidate();
}
// ITickable ------------------------------------------------------------------------------------
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing) {
if ((capability == ForgeCapabilities.FLUID_HANDLER) && has_milk_fluid()) return fluid_handler_.cast();
if ((capability == ForgeCapabilities.ENERGY) && (energy_consumption_ > 0)) return energy_handler_.cast();
return super.getCapability(capability, facing);
}
// ITickable ------------------------------------------------------------------------------------
private void log(String s) {
} // println("Milker|" + s); may be enabled with config, for dev was println
private static final HashMap<Integer, Long> tracked_cows_ = new HashMap<>();
private void log(String s)
{} // println("Milker|" + s); may be enabled with config, for dev was println
private static ItemStack milk_filled_container_item(ItemStack stack)
{ return milk_containers_.entrySet().stream().filter(e-> Inventories.areItemStacksIdentical(e.getKey(), stack)).map(Map.Entry::getValue).findFirst().orElse(ItemStack.EMPTY); }
private boolean fill_adjacent_inventory_item_containers(Direction block_facing)
{
private boolean fill_adjacent_inventory_item_containers(Direction block_facing) {
// Check inventory existence, back to down is preferred, otherwise sort back into same inventory.
IItemHandler src = Inventories.itemhandler(level, worldPosition.relative(block_facing), block_facing.getOpposite());
IItemHandler dst = Inventories.itemhandler(level, worldPosition.below(), Direction.UP);
if(src==null) { src = dst; } else if(dst==null) { dst = src; }
if (src == null) {
src = dst;
} else if (dst == null) {
dst = src;
}
if ((src == null) || (dst == null)) return false;
boolean dirty = false;
while ((tank_.getFluidAmount() >= BUCKET_SIZE)) {
@ -332,8 +337,7 @@ public class EdMilker
return dirty;
}
private boolean fill_adjacent_tank()
{
private boolean fill_adjacent_tank() {
if ((fluid_level() <= 0) || (!has_milk_fluid())) return false;
final FluidStack fs = new FluidStack(milk_fluid_, Math.max(fluid_level(), BUCKET_SIZE));
for (Direction dir : Direction.values()) {
@ -346,8 +350,7 @@ public class EdMilker
return false;
}
private void release_cow(Cow cow)
{
private void release_cow(Cow cow) {
log("release cow");
if (cow != null) {
cow.setNoAi(false);
@ -362,8 +365,7 @@ public class EdMilker
tick_timer_ = TICK_INTERVAL;
}
private boolean milking_process()
{
private boolean milking_process() {
if ((tracked_cow_ == null) && (fluid_level() >= MAX_MILKING_TANK_LEVEL)) return false; // nothing to do
final Direction facing = level.getBlockState(getBlockPos()).getValue(MilkerBlock.HORIZONTAL_FACING).getOpposite();
final Vec3 target_pos = Vec3.atLowerCornerOf(getBlockPos().relative(facing)).add(0.5, 0, 0.5);
@ -376,7 +378,8 @@ public class EdMilker
if (e.getUUID().equals(tracked_cow_)) return true;
if ((tracked_cow_ != null) || e.isBaby() || e.isInLove() || e.isVehicle()) return false;
if (!e.getNavigation().isDone()) return false;
if(Math.abs(tracked_cows_.getOrDefault(e.getId(), 0L)-t) < min_milking_delay_per_cow_ticks_) return false;
if (Math.abs(tracked_cows_.getOrDefault(e.getId(), 0L) - t) < min_milking_delay_per_cow_ticks_)
return false;
return true;
}
);
@ -386,10 +389,20 @@ public class EdMilker
cow = cows.get(level.random.nextInt(cows.size() - 1)); // pick one
}
}
if((state_ != MilkingState.IDLE) && ((state_timeout_ -= PROCESSING_TICK_INTERVAL) <= 0)) { release_cow(cow); log("Cow motion timeout"); cow = null; }
if((cow == null) || (!cow.isAlive())) { release_cow(cow); cow = null; }
if ((state_ != MilkingState.IDLE) && ((state_timeout_ -= PROCESSING_TICK_INTERVAL) <= 0)) {
release_cow(cow);
log("Cow motion timeout");
cow = null;
}
if ((cow == null) || (!cow.isAlive())) {
release_cow(cow);
cow = null;
}
if (tracked_cow_ == null) state_ = MilkingState.IDLE;
if(cow == null) { log("Init: No cow"); return false; } // retry next cycle
if (cow == null) {
log("Init: No cow");
return false;
} // retry next cycle
tick_timer_ = PROCESSING_TICK_INTERVAL;
state_timer_ -= PROCESSING_TICK_INTERVAL;
if (state_timer_ > 0) return false;
@ -407,7 +420,7 @@ public class EdMilker
}
return false;
}
if(cow.isLeashed() || cow.isBaby() || cow.isInLove() || (!cow.isOnGround()) || cow.isVehicle() || cow.isSprinting())
if (cow.isLeashed() || cow.isBaby() || cow.isInLove() || (!cow.onGround()) || cow.isVehicle() || cow.isSprinting())
return false;
tracked_cows_.put(cow.getId(), cow.getCommandSenderWorld().getGameTime());
tracked_cow_ = cow.getUUID();
@ -493,8 +506,7 @@ public class EdMilker
}
@Override
public void tick()
{
public void tick() {
if ((level.isClientSide) || ((--tick_timer_ > 0))) return;
tick_timer_ = TICK_INTERVAL;
boolean dirty = false;
@ -521,7 +533,8 @@ public class EdMilker
// Adjacent inventory update, only done just after milking to prevent waste of server cpu.
if ((!dirty) && (fluid_level() > 0)) {
log("Try item transfer");
if(fill_adjacent_tank() || ((fluid_level() >= BUCKET_SIZE) && fill_adjacent_inventory_item_containers(block_state.getValue(MilkerBlock.HORIZONTAL_FACING)))) dirty = true;
if (fill_adjacent_tank() || ((fluid_level() >= BUCKET_SIZE) && fill_adjacent_inventory_item_containers(block_state.getValue(MilkerBlock.HORIZONTAL_FACING))))
dirty = true;
}
}
// State update
@ -529,14 +542,11 @@ public class EdMilker
if (block_state != new_state) level.setBlock(worldPosition, new_state, 1 | 2 | 16);
if (dirty) setChanged();
}
private enum MilkingState {IDLE, PICKED, COMING, POSITIONING, MILKING, LEAVING, WAITING}
}
public static class SingleMoveGoal extends MoveToBlockGoal
{
@FunctionalInterface public interface TargetPositionInValidCheck { boolean test(SingleMoveGoal goal, LevelReader world, BlockPos pos); }
@FunctionalInterface public interface StrollEvent { void apply(SingleMoveGoal goal, LevelReader world, Vec3 pos); }
private static void log(String s) {} // println("SingleMoveGoal: "+s);
public static class SingleMoveGoal extends MoveToBlockGoal {
private static final HashMap<Integer, SingleMoveGoal> tracked_entities_ = new HashMap<>();
private static final int motion_timeout = 20 * 20;
private boolean aborted_;
@ -546,9 +556,7 @@ public class EdMilker
private TargetPositionInValidCheck abort_condition_;
private StrollEvent on_target_position_reached_;
private StrollEvent on_aborted_;
public SingleMoveGoal(PathfinderMob creature, Vec3 pos, double speed, TargetPositionInValidCheck abort_condition, @Nullable StrollEvent on_position_reached, @Nullable StrollEvent on_aborted)
{
public SingleMoveGoal(PathfinderMob creature, Vec3 pos, double speed, TargetPositionInValidCheck abort_condition, @Nullable StrollEvent on_position_reached, @Nullable StrollEvent on_aborted) {
super(creature, speed, 32, 32);
abort_condition_ = abort_condition;
on_target_position_reached_ = on_position_reached;
@ -561,11 +569,14 @@ public class EdMilker
target_pos_ = pos;
}
public static void startFor(PathfinderMob entity, BlockPos target_pos, int priority, double speed, TargetPositionInValidCheck abort_condition)
{ startFor(entity, new Vec3(target_pos.getX(),target_pos.getY(),target_pos.getZ()), priority, speed, abort_condition, null, null); }
private static void log(String s) {
} // println("SingleMoveGoal: "+s);
public static boolean startFor(PathfinderMob entity, Vec3 target_pos, int priority, double speed, TargetPositionInValidCheck abort_condition, @Nullable StrollEvent on_position_reached, @Nullable StrollEvent on_aborted)
{
public static void startFor(PathfinderMob entity, BlockPos target_pos, int priority, double speed, TargetPositionInValidCheck abort_condition) {
startFor(entity, new Vec3(target_pos.getX(), target_pos.getY(), target_pos.getZ()), priority, speed, abort_condition, null, null);
}
public static boolean startFor(PathfinderMob entity, Vec3 target_pos, int priority, double speed, TargetPositionInValidCheck abort_condition, @Nullable StrollEvent on_position_reached, @Nullable StrollEvent on_aborted) {
synchronized (tracked_entities_) {
SingleMoveGoal goal = tracked_entities_.getOrDefault(entity.getId(), null);
if (goal != null) {
@ -580,13 +591,13 @@ public class EdMilker
}
}
public static boolean isActiveFor(PathfinderMob entity)
{ return (entity != null) && (entity.goalSelector.getRunningGoals().anyMatch(
public static boolean isActiveFor(PathfinderMob entity) {
return (entity != null) && (entity.goalSelector.getRunningGoals().anyMatch(
g -> ((g.getGoal()) instanceof SingleMoveGoal) && (!((SingleMoveGoal) (g.getGoal())).aborted())
)); }
));
}
public static void abortFor(PathfinderMob entity)
{
public static void abortFor(PathfinderMob entity) {
log("::abort(" + entity.getId() + ")");
if (entity.isAlive()) {
entity.goalSelector.getRunningGoals().filter(g -> (g.getGoal()) instanceof SingleMoveGoal).forEach(g -> ((SingleMoveGoal) g.getGoal()).abort());
@ -599,20 +610,23 @@ public class EdMilker
}
}
public Vec3 getTargetPosition()
{ return target_pos_; }
public Vec3 getTargetPosition() {
return target_pos_;
}
public PathfinderMob getCreature()
{ return mob; }
public PathfinderMob getCreature() {
return mob;
}
public synchronized void abort()
{ aborted_ = true; }
public synchronized void abort() {
aborted_ = true;
}
public synchronized boolean aborted()
{ return aborted_; }
public synchronized boolean aborted() {
return aborted_;
}
public synchronized void initialize(Vec3 target_pos, double speed, TargetPositionInValidCheck abort_condition, @Nullable StrollEvent on_position_reached, @Nullable StrollEvent on_aborted)
{
public synchronized void initialize(Vec3 target_pos, double speed, TargetPositionInValidCheck abort_condition, @Nullable StrollEvent on_position_reached, @Nullable StrollEvent on_aborted) {
abort_condition_ = abort_condition;
on_target_position_reached_ = on_position_reached;
on_aborted_ = on_aborted;
@ -626,26 +640,31 @@ public class EdMilker
}
@Override
public void stop()
{ nextStartTick = 0; tryTicks = 0; }
public void stop() {
nextStartTick = 0;
tryTicks = 0;
}
@Override
public double acceptedDistance()
{ return 0.7; }
public double acceptedDistance() {
return 0.7;
}
@Override
public boolean shouldRecalculatePath()
{ return (!aborted()) && (tryTicks & 0x7) == 0; }
public boolean shouldRecalculatePath() {
return (!aborted()) && (tryTicks & 0x7) == 0;
}
@Override
public boolean canUse()
{
public boolean canUse() {
if (aborted_) {
if((!was_aborted_) && (on_aborted_!=null)) on_aborted_.apply(this, mob.level, target_pos_);
if ((!was_aborted_) && (on_aborted_ != null)) on_aborted_.apply(this, mob.level(), target_pos_);
was_aborted_ = true;
return false;
} else if(!isValidTarget(mob.level, blockPos)) {
synchronized(this) { aborted_ = true; }
} else if (!isValidTarget(mob.level(), blockPos)) {
synchronized (this) {
aborted_ = true;
}
return false;
} else if (--nextStartTick > 0) {
return false;
@ -656,8 +675,7 @@ public class EdMilker
}
@Override
public void start()
{
public void start() {
tryTicks = 0;
if (!mob.getNavigation().moveTo(target_pos_.x(), target_pos_.y(), target_pos_.z(), this.speedModifier)) {
abort();
@ -667,8 +685,7 @@ public class EdMilker
}
}
public boolean canContinueToUse()
{
public boolean canContinueToUse() {
if (aborted()) {
log("shouldContinueExecuting() -> already aborted");
return false;
@ -684,7 +701,7 @@ public class EdMilker
log("shouldContinueExecuting() -> abort, timeout");
abort();
return false;
} else if(!isValidTarget(mob.level, blockPos)) {
} else if (!isValidTarget(mob.level(), blockPos)) {
log("shouldContinueExecuting() -> abort, !shouldMoveTo()");
abort();
return false;
@ -695,8 +712,7 @@ public class EdMilker
}
@Override
protected boolean isValidTarget(LevelReader world, BlockPos pos)
{
protected boolean isValidTarget(LevelReader world, BlockPos pos) {
if (abort_condition_.test(this, world, pos)) {
log("shouldMoveTo() -> abort_condition");
return false;
@ -706,9 +722,8 @@ public class EdMilker
}
@Override
public void tick()
{
final BlockPos testpos = new BlockPos(target_pos_.x(), mob.position().y(), target_pos_.z());
public void tick() {
final BlockPos testpos = new BlockPos((int) target_pos_.x(), (int) mob.position().y(), (int) target_pos_.z());
if (!testpos.closerToCenterThan(mob.position(), acceptedDistance())) {
if ((++tryTicks > motion_timeout)) {
log("tick() -> abort, timeoutCounter");
@ -723,8 +738,19 @@ public class EdMilker
log("tick() -> abort, in position)");
in_position_ = true;
abort();
if(on_target_position_reached_ != null) on_target_position_reached_.apply(this, mob.level, target_pos_);
}
if (on_target_position_reached_ != null)
on_target_position_reached_.apply(this, mob.level(), target_pos_);
}
}
@FunctionalInterface
public interface TargetPositionInValidCheck {
boolean test(SingleMoveGoal goal, LevelReader world, BlockPos pos);
}
@FunctionalInterface
public interface StrollEvent {
void apply(SingleMoveGoal goal, LevelReader world, Vec3 pos);
}
}
}

View file

@ -9,6 +9,9 @@
*/
package dev.zontreck.engineerdecor.blocks;
import dev.zontreck.engineerdecor.ModConfig;
import dev.zontreck.engineerdecor.ModContent;
import dev.zontreck.libzontreck.edlibmc.*;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.particles.ParticleOptions;
@ -29,7 +32,7 @@ import net.minecraft.world.item.Items;
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.SignalGetter;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BlockEntity;
@ -51,77 +54,80 @@ import net.minecraftforge.energy.IEnergyStorage;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.items.IItemHandler;
import dev.zontreck.engineerdecor.ModConfig;
import dev.zontreck.engineerdecor.ModContent;
import dev.zontreck.engineerdecor.libmc.StandardBlocks;
import dev.zontreck.engineerdecor.libmc.StandardEntityBlocks;
import dev.zontreck.engineerdecor.libmc.Auxiliaries;
import dev.zontreck.engineerdecor.libmc.Fluidics;
import dev.zontreck.engineerdecor.libmc.Inventories;
import dev.zontreck.engineerdecor.libmc.RfEnergy;
import javax.annotation.Nullable;
import java.util.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class EdMineralSmelter
{
public static void on_config(int consumption, int heatup_per_second)
{ MineralSmelterTileEntity.on_config(consumption, heatup_per_second); }
public class EdMineralSmelter {
public static void on_config(int consumption, int heatup_per_second) {
MineralSmelterTileEntity.on_config(consumption, heatup_per_second);
}
//--------------------------------------------------------------------------------------------------------------------
// Block
//--------------------------------------------------------------------------------------------------------------------
public static class MineralSmelterBlock extends StandardBlocks.Horizontal implements StandardEntityBlocks.IStandardEntityBlock<MineralSmelterTileEntity>
{
public static class MineralSmelterBlock extends StandardBlocks.Horizontal implements StandardEntityBlocks.IStandardEntityBlock<MineralSmelterTileEntity> {
public static final int PHASE_MAX = 3;
public static final IntegerProperty PHASE = IntegerProperty.create("phase", 0, PHASE_MAX);
public MineralSmelterBlock(long config, BlockBehaviour.Properties builder, final AABB unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
public MineralSmelterBlock(long config, BlockBehaviour.Properties builder, final AABB unrotatedAABB) {
super(config, builder, unrotatedAABB);
}
@Override
public boolean isBlockEntityTicking(Level world, BlockState state)
{ return true; }
public boolean isBlockEntityTicking(Level world, BlockState state) {
return true;
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext)
{ return Shapes.block(); }
public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) {
return Shapes.block();
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder)
{ super.createBlockStateDefinition(builder); builder.add(PHASE); }
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
super.createBlockStateDefinition(builder);
builder.add(PHASE);
}
@Override
@Nullable
public BlockState getStateForPlacement(BlockPlaceContext context)
{ return super.getStateForPlacement(context).setValue(PHASE, 0); }
public BlockState getStateForPlacement(BlockPlaceContext context) {
return super.getStateForPlacement(context).setValue(PHASE, 0);
}
@Override
@SuppressWarnings("deprecation")
public boolean hasAnalogOutputSignal(BlockState state)
{ return true; }
public boolean hasAnalogOutputSignal(BlockState state) {
return true;
}
@Override
@SuppressWarnings("deprecation")
public int getAnalogOutputSignal(BlockState state, Level world, BlockPos pos)
{ return Mth.clamp((state.getValue(PHASE)*5), 0, 15); }
public int getAnalogOutputSignal(BlockState state, Level world, BlockPos pos) {
return Mth.clamp((state.getValue(PHASE) * 5), 0, 15);
}
@Override
public boolean shouldCheckWeakPower(BlockState state, LevelReader world, BlockPos pos, Direction side)
{ return false; }
public boolean shouldCheckWeakPower(BlockState state, SignalGetter level, BlockPos pos, Direction side) {
return false;
}
@Override
public void setPlacedBy(Level world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack)
{}
public void setPlacedBy(Level world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) {
}
@Override
public boolean hasDynamicDropList()
{ return true; }
public boolean hasDynamicDropList() {
return true;
}
@Override
public List<ItemStack> dropList(BlockState state, Level world, BlockEntity te, boolean explosion)
{
public List<ItemStack> dropList(BlockState state, Level world, BlockEntity te, boolean explosion) {
final List<ItemStack> stacks = new ArrayList<>();
if (world.isClientSide) return stacks;
if (!(te instanceof MineralSmelterTileEntity)) return stacks;
@ -132,8 +138,7 @@ public class EdMineralSmelter
@Override
@SuppressWarnings("deprecation")
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult rayTraceResult)
{
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult rayTraceResult) {
if (player.isShiftKeyDown()) return InteractionResult.PASS;
if (world.isClientSide()) return InteractionResult.SUCCESS;
MineralSmelterTileEntity te = getTe(world, pos);
@ -141,7 +146,7 @@ public class EdMineralSmelter
final ItemStack stack = player.getItemInHand(hand);
boolean dirty = false;
if (te.accepts_lava_container(stack)) {
if(stack.sameItemStackIgnoreDurability(MineralSmelterTileEntity.BUCKET_STACK)) { // check how this works with item capabilities or so
if (stack.is(MineralSmelterTileEntity.BUCKET_STACK.getItem())) { // check how this works with item capabilities or so
if (te.bucket_extraction_possible()) {
if (stack.getCount() > 1) {
int target_stack_index = -1;
@ -184,8 +189,7 @@ public class EdMineralSmelter
@Override
@OnlyIn(Dist.CLIENT)
public void animateTick(BlockState state, Level world, BlockPos pos, RandomSource rnd)
{
public void animateTick(BlockState state, Level world, BlockPos pos, RandomSource rnd) {
if (state.getBlock() != this) return;
ParticleOptions particle = ParticleTypes.SMOKE;
switch (state.getValue(PHASE)) {
@ -211,16 +215,17 @@ public class EdMineralSmelter
}
@Nullable
private MineralSmelterTileEntity getTe(Level world, BlockPos pos)
{ final BlockEntity te=world.getBlockEntity(pos); return (!(te instanceof MineralSmelterTileEntity)) ? (null) : ((MineralSmelterTileEntity)te); }
private MineralSmelterTileEntity getTe(Level world, BlockPos pos) {
final BlockEntity te = world.getBlockEntity(pos);
return (!(te instanceof MineralSmelterTileEntity)) ? (null) : ((MineralSmelterTileEntity) te);
}
}
//--------------------------------------------------------------------------------------------------------------------
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
public static class MineralSmelterTileEntity extends StandardEntityBlocks.StandardBlockEntity
{
public static class MineralSmelterTileEntity extends StandardEntityBlocks.StandardBlockEntity {
public static final int NUM_OF_SLOTS = 2;
public static final int TICK_INTERVAL = 20;
public static final int MAX_FLUID_LEVEL = 2000;
@ -242,9 +247,10 @@ public class EdMineralSmelter
private static int energy_consumption = DEFAULT_ENERGY_CONSUMPTION;
private static int heatup_rate = DEFAULT_HEATUP_RATE;
private static int cooldown_rate = 1;
private int tick_timer_;
private int progress_;
private boolean force_block_update_;
static {
accepted_lava_contrainers.add(Items.BUCKET);
}
private final RfEnergy.Battery battery_ = new RfEnergy.Battery(MAX_ENERGY_BUFFER, MAX_ENERGY_TRANSFER, 0);
private final LazyOptional<IEnergyStorage> energy_handler_ = battery_.createEnergyHandler();
@ -252,54 +258,56 @@ public class EdMineralSmelter
private final LazyOptional<? extends IFluidHandler> fluid_handler_ = tank_.createOutputFluidHandler();
private final Inventories.StorageInventory main_inventory_;
private final LazyOptional<? extends IItemHandler> item_handler_;
private int tick_timer_;
private int progress_;
private boolean force_block_update_;
static {
accepted_lava_contrainers.add(Items.BUCKET);
}
public static void on_config(int consumption, int heatup_per_second)
{
energy_consumption = Mth.clamp(consumption, 8, 4096);
heatup_rate = Mth.clamp(heatup_per_second, 1, 5);
cooldown_rate = Mth.clamp(heatup_per_second/2, 1, 5);
ModConfig.log("Config mineal smelter: energy consumption:" + energy_consumption + "rf/t, heat-up rate: " + heatup_rate + "%/s.");
}
public MineralSmelterTileEntity(BlockPos pos, BlockState state)
{
public MineralSmelterTileEntity(BlockPos pos, BlockState state) {
super(ModContent.getBlockEntityTypeOfBlock(state.getBlock()), pos, state);
main_inventory_ = (new Inventories.StorageInventory(this, NUM_OF_SLOTS, 1)).setStackLimit(1);
item_handler_ = Inventories.MappedItemHandler.createGenericHandler(
main_inventory_,
(index, stack) -> ((index == 1) && (phase() != PHASE_LAVA)),
(index, stack) -> ((index == 0) && (progress_ == 0) && accepts_input(stack)),
(index,stack)->{},
(index,stack)->{ if(index!=0) reset_process(); }
(index, stack) -> {
},
(index, stack) -> {
if (index != 0) reset_process();
}
);
}
public int progress()
{ return progress_; }
public static void on_config(int consumption, int heatup_per_second) {
energy_consumption = Mth.clamp(consumption, 8, 4096);
heatup_rate = Mth.clamp(heatup_per_second, 1, 5);
cooldown_rate = Mth.clamp(heatup_per_second / 2, 1, 5);
ModConfig.log("Config mineal smelter: energy consumption:" + energy_consumption + "rf/t, heat-up rate: " + heatup_rate + "%/s.");
}
public int phase()
{
public int progress() {
return progress_;
}
public int phase() {
if (progress_ >= 100) return PHASE_LAVA;
if (progress_ >= 90) return PHASE_MAGMABLOCK;
if (progress_ >= 5) return PHASE_HOT;
return PHASE_WARMUP;
}
public boolean bucket_extraction_possible()
{ return tank_.getFluidAmount() >= MAX_BUCKET_EXTRACT_FLUID_LEVEL; }
public boolean bucket_extraction_possible() {
return tank_.getFluidAmount() >= MAX_BUCKET_EXTRACT_FLUID_LEVEL;
}
public int comparator_signal()
{ return phase() * 5; }
public int comparator_signal() {
return phase() * 5;
}
private boolean accepts_lava_container(ItemStack stack)
{ return accepted_lava_contrainers.contains(stack.getItem()); }
private boolean accepts_lava_container(ItemStack stack) {
return accepted_lava_contrainers.contains(stack.getItem());
}
private boolean accepts_input(ItemStack stack)
{
private boolean accepts_input(ItemStack stack) {
if (!main_inventory_.isEmpty()) {
return false;
} else if (bucket_extraction_possible()) {
@ -309,8 +317,7 @@ public class EdMineralSmelter
}
}
public boolean insert(final ItemStack stack, boolean simulate)
{
public boolean insert(final ItemStack stack, boolean simulate) {
if (stack.isEmpty() || (!accepts_input(stack))) return false;
if (!simulate) {
final ItemStack st = stack.copy();
@ -322,16 +329,14 @@ public class EdMineralSmelter
return true;
}
public ItemStack extract(boolean simulate)
{
public ItemStack extract(boolean simulate) {
final ItemStack stack = main_inventory_.getItem(1).copy();
if (stack.isEmpty()) return ItemStack.EMPTY;
if (!simulate) reset_process();
return stack;
}
protected void reset_process()
{
protected void reset_process() {
main_inventory_.setItem(0, ItemStack.EMPTY);
main_inventory_.setItem(1, ItemStack.EMPTY);
tank_.clear();
@ -340,16 +345,14 @@ public class EdMineralSmelter
progress_ = 0;
}
public void readnbt(CompoundTag nbt)
{
public void readnbt(CompoundTag nbt) {
main_inventory_.load(nbt);
battery_.load(nbt);
tank_.load(nbt);
progress_ = nbt.getInt("progress");
}
protected void writenbt(CompoundTag nbt)
{
protected void writenbt(CompoundTag nbt) {
main_inventory_.save(nbt);
battery_.save(nbt);
tank_.save(nbt);
@ -359,16 +362,19 @@ public class EdMineralSmelter
// BlockEntity ------------------------------------------------------------------------------
@Override
public void load(CompoundTag nbt)
{ super.load(nbt); readnbt(nbt); }
public void load(CompoundTag nbt) {
super.load(nbt);
readnbt(nbt);
}
@Override
protected void saveAdditional(CompoundTag nbt)
{ super.saveAdditional(nbt); writenbt(nbt); }
protected void saveAdditional(CompoundTag nbt) {
super.saveAdditional(nbt);
writenbt(nbt);
}
@Override
public void setRemoved()
{
public void setRemoved() {
super.setRemoved();
energy_handler_.invalidate();
fluid_handler_.invalidate();
@ -378,8 +384,7 @@ public class EdMineralSmelter
// Capability export ----------------------------------------------------------------------------
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing) {
if (capability == ForgeCapabilities.ITEM_HANDLER) return item_handler_.cast();
if (capability == ForgeCapabilities.FLUID_HANDLER) return fluid_handler_.cast();
if (capability == ForgeCapabilities.ENERGY) return energy_handler_.cast();
@ -389,8 +394,7 @@ public class EdMineralSmelter
// ITickable ------------------------------------------------------------------------------------
@Override
public void tick()
{
public void tick() {
if (--tick_timer_ > 0) return;
tick_timer_ = TICK_INTERVAL;
BlockState state = level.getBlockState(worldPosition);
@ -414,8 +418,8 @@ public class EdMineralSmelter
final int new_phase = phase();
if (accepts_lava_container(istack)) {
// That stays in the slot until its extracted or somone takes it out.
if(istack.sameItem(BUCKET_STACK)) {
if(!main_inventory_.getItem(1).sameItem(LAVA_BUCKET_STACK)) {
if (istack.is(BUCKET_STACK.getItem())) {
if (!main_inventory_.getItem(1).is(LAVA_BUCKET_STACK.getItem())) {
if (bucket_extraction_possible()) {
reset_process();
main_inventory_.setItem(1, LAVA_BUCKET_STACK);
@ -463,7 +467,7 @@ public class EdMineralSmelter
dirty = true;
}
case PHASE_HOT -> {
if(istack.sameItem(MAGMA_STACK)) {
if (istack.is(MAGMA_STACK.getItem())) {
main_inventory_.setItem(1, new ItemStack(Blocks.OBSIDIAN));
} else {
main_inventory_.setItem(1, new ItemStack(Blocks.COBBLESTONE));

View file

@ -9,6 +9,11 @@
*/
package dev.zontreck.engineerdecor.blocks;
import dev.zontreck.engineerdecor.ModConfig;
import dev.zontreck.engineerdecor.ModContent;
import dev.zontreck.libzontreck.edlibmc.RsSignals;
import dev.zontreck.libzontreck.edlibmc.StandardBlocks;
import dev.zontreck.libzontreck.edlibmc.StandardEntityBlocks;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.util.Mth;
@ -18,7 +23,7 @@ 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.SignalGetter;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Rotation;
import net.minecraft.world.level.block.entity.BlockEntity;
@ -35,24 +40,17 @@ import net.minecraftforge.common.capabilities.ForgeCapabilities;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.IFluidHandler;
import dev.zontreck.engineerdecor.ModConfig;
import dev.zontreck.engineerdecor.ModContent;
import dev.zontreck.engineerdecor.libmc.StandardBlocks;
import dev.zontreck.engineerdecor.libmc.StandardEntityBlocks;
import dev.zontreck.engineerdecor.libmc.RsSignals;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
public class EdPipeValve
{
public class EdPipeValve {
public static final int CFG_CHECK_VALVE = 0x1;
public static final int CFG_ANALOG_VALVE = 0x2;
public static final int CFG_REDSTONE_CONTROLLED_VALVE = 0x4;
public static void on_config(int container_size_decl, int redstone_slope)
{
public static void on_config(int container_size_decl, int redstone_slope) {
PipeValveTileEntity.fluid_maxflow_mb = Mth.clamp(container_size_decl, 1, 10000);
PipeValveTileEntity.redstone_flow_slope_mb = Mth.clamp(redstone_slope, 1, 10000);
ModConfig.log("Config pipe valve: maxflow:" + PipeValveTileEntity.fluid_maxflow_mb + "mb, redstone amp:" + PipeValveTileEntity.redstone_flow_slope_mb + "mb/sig.");
@ -62,8 +60,7 @@ public class EdPipeValve
// Block
//--------------------------------------------------------------------------------------------------------------------
public static class PipeValveBlock extends StandardBlocks.DirectedWaterLoggable implements StandardEntityBlocks.IStandardEntityBlock<PipeValveTileEntity>
{
public static class PipeValveBlock extends StandardBlocks.DirectedWaterLoggable implements StandardEntityBlocks.IStandardEntityBlock<PipeValveTileEntity> {
public static final BooleanProperty RS_CN_N = BooleanProperty.create("rs_n");
public static final BooleanProperty RS_CN_S = BooleanProperty.create("rs_s");
public static final BooleanProperty RS_CN_E = BooleanProperty.create("rs_e");
@ -72,84 +69,98 @@ public class EdPipeValve
public static final BooleanProperty RS_CN_D = BooleanProperty.create("rs_d");
public final int valve_config;
public PipeValveBlock(long config, int valve_config, BlockBehaviour.Properties builder, final AABB[] unrotatedAABB)
{ super(config, builder, unrotatedAABB); this.valve_config = valve_config; }
public PipeValveBlock(long config, int valve_config, BlockBehaviour.Properties builder, final AABB[] unrotatedAABB) {
super(config, builder, unrotatedAABB);
this.valve_config = valve_config;
}
@Override
@Nullable
public BlockEntity newBlockEntity(BlockPos pos, BlockState state)
{
public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
final BlockEntityType<?> tet = ModContent.getBlockEntityTypeOfBlock("straight_pipe_valve");
return (tet == null) ? null : tet.create(pos, state);
}
@Override
public boolean isBlockEntityTicking(Level world, BlockState state)
{ return false; }
public boolean isBlockEntityTicking(Level world, BlockState state) {
return false;
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext)
{ return Shapes.block(); }
public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) {
return Shapes.block();
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder)
{ super.createBlockStateDefinition(builder); builder.add(RS_CN_N, RS_CN_S, RS_CN_E, RS_CN_W, RS_CN_U, RS_CN_D); }
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
super.createBlockStateDefinition(builder);
builder.add(RS_CN_N, RS_CN_S, RS_CN_E, RS_CN_W, RS_CN_U, RS_CN_D);
}
@Override
@Nullable
public BlockState getStateForPlacement(BlockPlaceContext context)
{
public BlockState getStateForPlacement(BlockPlaceContext context) {
return super.getStateForPlacement(context).setValue(RS_CN_N, false).setValue(RS_CN_S, false).setValue(RS_CN_E, false)
.setValue(RS_CN_W, false).setValue(RS_CN_U, false).setValue(RS_CN_D, false);
}
@Override
@SuppressWarnings("deprecation")
public BlockState updateShape(BlockState state, Direction facing, BlockState facingState, LevelAccessor world, BlockPos pos, BlockPos facingPos)
{ return get_rsconnector_state(state, world, pos, null); }
public BlockState updateShape(BlockState state, Direction facing, BlockState facingState, LevelAccessor world, BlockPos pos, BlockPos facingPos) {
return get_rsconnector_state(state, world, pos, null);
}
@Override
public void setPlacedBy(Level world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack)
{ world.updateNeighborsAt(pos,this); }
public void setPlacedBy(Level world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) {
world.updateNeighborsAt(pos, this);
}
@Override
public BlockState rotate(BlockState state, LevelAccessor world, BlockPos pos, Rotation direction)
{ return get_rsconnector_state(state, world, pos, null); } // don't rotate at all
public BlockState rotate(BlockState state, LevelAccessor world, BlockPos pos, Rotation direction) {
return get_rsconnector_state(state, world, pos, null);
} // don't rotate at all
@Override
public boolean hasSignalConnector(BlockState state, BlockGetter world, BlockPos pos, @Nullable Direction side)
{ return (side!=null) && (side!=state.getValue(FACING)) && (side!=state.getValue(FACING).getOpposite()); }
public boolean hasSignalConnector(BlockState state, BlockGetter world, BlockPos pos, @Nullable Direction side) {
return (side != null) && (side != state.getValue(FACING)) && (side != state.getValue(FACING).getOpposite());
}
@Override
public boolean shouldCheckWeakPower(BlockState state, LevelReader world, BlockPos pos, Direction side)
{ return false; }
@Override
@SuppressWarnings("deprecation") // public boolean canConnectRedstone(BlockState state, BlockGetter world, BlockPos pos, @Nullable Direction side) { return true; }
public boolean isSignalSource(BlockState p_60571_)
{ return true; }
public boolean shouldCheckWeakPower(BlockState state, SignalGetter level, BlockPos pos, Direction side) {
return false;
}
@Override
@SuppressWarnings("deprecation")
public int getSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side)
{ return 0; }
// public boolean canConnectRedstone(BlockState state, BlockGetter world, BlockPos pos, @Nullable Direction side) { return true; }
public boolean isSignalSource(BlockState p_60571_) {
return true;
}
@Override
@SuppressWarnings("deprecation")
public int getDirectSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side)
{ return 0; }
public int getSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side) {
return 0;
}
private BlockState get_rsconnector_state(BlockState state, LevelAccessor world, BlockPos pos, @Nullable BlockPos fromPos)
{
@Override
@SuppressWarnings("deprecation")
public int getDirectSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side) {
return 0;
}
private BlockState get_rsconnector_state(BlockState state, LevelAccessor world, BlockPos pos, @Nullable BlockPos fromPos) {
if ((valve_config & (CFG_REDSTONE_CONTROLLED_VALVE)) == 0) return state;
Direction.Axis bfa = state.getValue(FACING).getAxis();
for (Direction f : Direction.values()) {
boolean cn = (f.getAxis() != bfa);
if (cn) {
BlockPos nbp = pos.relative(f);
if((fromPos != null) && (!nbp.equals(fromPos))) continue; // do not change connectors except form the frompos.
if ((fromPos != null) && (!nbp.equals(fromPos)))
continue; // do not change connectors except form the frompos.
BlockState nbs = world.getBlockState(nbp);
if((nbs.getBlock() instanceof PipeValveBlock) || (!nbs.isSignalSource()) || (!RsSignals.hasSignalConnector(nbs, world, nbp, f.getOpposite()))) cn = false;
if ((nbs.getBlock() instanceof PipeValveBlock) || (!nbs.isSignalSource()) || (!RsSignals.hasSignalConnector(nbs, world, nbp, f.getOpposite())))
cn = false;
}
switch (f) {
case NORTH -> state = state.setValue(RS_CN_N, cn);
@ -169,25 +180,29 @@ public class EdPipeValve
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
public static class PipeValveTileEntity extends StandardEntityBlocks.StandardBlockEntity
{
public static class PipeValveTileEntity extends StandardEntityBlocks.StandardBlockEntity {
protected static int fluid_maxflow_mb = 1000;
protected static int redstone_flow_slope_mb = 1000 / 15;
private final Direction block_facing_ = null;
private final LazyOptional<IFluidHandler> back_flow_handler_ = LazyOptional.of(BackFlowHandler::new);
private final LazyOptional<IFluidHandler> fluid_handler_ = LazyOptional.of(() -> new MainFlowHandler(this));
private boolean filling_ = false;
private int valve_config_;
public PipeValveTileEntity(BlockPos pos, BlockState state)
{ super(ModContent.getBlockEntityTypeOfBlock("straight_pipe_valve"), pos, state); }
public PipeValveTileEntity(BlockPos pos, BlockState state) {
super(ModContent.getBlockEntityTypeOfBlock("straight_pipe_valve"), pos, state);
}
private Direction block_facing()
{
// BlockEntity -----------------------------------------------------------------------------
private Direction block_facing() {
BlockState st = getLevel().getBlockState(getBlockPos());
return (st.getBlock() instanceof PipeValveBlock) ? st.getValue(PipeValveBlock.FACING) : Direction.NORTH;
}
private long valve_config()
{
// ICapabilityProvider --------------------------------------------------------------------
private long valve_config() {
if (valve_config_ <= 0) {
final Block block = getLevel().getBlockState(getBlockPos()).getBlock();
if (block instanceof PipeValveBlock) valve_config_ = ((PipeValveBlock) block).valve_config;
@ -195,24 +210,15 @@ public class EdPipeValve
return valve_config_;
}
// BlockEntity -----------------------------------------------------------------------------
@Override
public void setRemoved()
{
public void setRemoved() {
super.setRemoved();
back_flow_handler_.invalidate();
fluid_handler_.invalidate();
}
// ICapabilityProvider --------------------------------------------------------------------
private final LazyOptional<IFluidHandler> back_flow_handler_ = LazyOptional.of(BackFlowHandler::new);
private final LazyOptional<IFluidHandler> fluid_handler_ = LazyOptional.of(() -> new MainFlowHandler(this));
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing) {
if (capability == ForgeCapabilities.FLUID_HANDLER) {
Direction bf = block_facing();
if (facing == bf) return back_flow_handler_.cast();
@ -225,8 +231,7 @@ public class EdPipeValve
// IFluidHandlers
@Nullable
private IFluidHandler forward_fluid_handler()
{
private IFluidHandler forward_fluid_handler() {
final BlockEntity te = level.getBlockEntity(worldPosition.relative(block_facing()));
if (te == null) return null;
return te.getCapability(ForgeCapabilities.FLUID_HANDLER, block_facing().getOpposite()).orElse(null);
@ -234,19 +239,45 @@ public class EdPipeValve
// Forward flow handler --
private static class MainFlowHandler implements IFluidHandler
{
private static class MainFlowHandler implements IFluidHandler {
private final PipeValveTileEntity te;
public MainFlowHandler(PipeValveTileEntity te) { this.te = te; }
@Override public int getTanks() { return 1; }
@Override public FluidStack getFluidInTank(int tank) { return FluidStack.EMPTY; }
@Override public int getTankCapacity(int tank) { return fluid_maxflow_mb; }
@Override public boolean isFluidValid(int tank, @Nonnull FluidStack stack) { return true; }
@Override public FluidStack drain(FluidStack resource, FluidAction action) { return FluidStack.EMPTY; }
@Override public FluidStack drain(int maxDrain, FluidAction action) { return FluidStack.EMPTY; }
@Override public int fill(FluidStack resource, FluidAction action)
{
public MainFlowHandler(PipeValveTileEntity te) {
this.te = te;
}
@Override
public int getTanks() {
return 1;
}
@Override
public FluidStack getFluidInTank(int tank) {
return FluidStack.EMPTY;
}
@Override
public int getTankCapacity(int tank) {
return fluid_maxflow_mb;
}
@Override
public boolean isFluidValid(int tank, @Nonnull FluidStack stack) {
return true;
}
@Override
public FluidStack drain(FluidStack resource, FluidAction action) {
return FluidStack.EMPTY;
}
@Override
public FluidStack drain(int maxDrain, FluidAction action) {
return FluidStack.EMPTY;
}
@Override
public int fill(FluidStack resource, FluidAction action) {
if (te.filling_) return 0;
final IFluidHandler fh = te.forward_fluid_handler();
if (fh == null) return 0;
@ -254,7 +285,8 @@ public class EdPipeValve
if ((te.valve_config() & CFG_REDSTONE_CONTROLLED_VALVE) != 0) {
int rs = te.level.getBestNeighborSignal(te.worldPosition);
if (rs <= 0) return 0;
if(((te.valve_config() & CFG_ANALOG_VALVE) != 0) && (rs < 15)) res.setAmount(Mth.clamp(rs * redstone_flow_slope_mb, 1, res.getAmount()));
if (((te.valve_config() & CFG_ANALOG_VALVE) != 0) && (rs < 15))
res.setAmount(Mth.clamp(rs * redstone_flow_slope_mb, 1, res.getAmount()));
}
if (res.getAmount() > fluid_maxflow_mb) res.setAmount(fluid_maxflow_mb);
te.filling_ = true;
@ -266,15 +298,41 @@ public class EdPipeValve
// Back flow prevention handler --
private static class BackFlowHandler implements IFluidHandler
{
@Override public int getTanks() { return 1; }
@Override public FluidStack getFluidInTank(int tank) { return FluidStack.EMPTY; }
@Override public int getTankCapacity(int tank) { return 0; }
@Override public boolean isFluidValid(int tank, @Nonnull FluidStack stack) { return false; }
@Override public int fill(FluidStack resource, FluidAction action) { return 0; }
@Override public FluidStack drain(FluidStack resource, FluidAction action) { return FluidStack.EMPTY; }
@Override public FluidStack drain(int maxDrain, FluidAction action) { return FluidStack.EMPTY; }
private static class BackFlowHandler implements IFluidHandler {
@Override
public int getTanks() {
return 1;
}
@Override
public FluidStack getFluidInTank(int tank) {
return FluidStack.EMPTY;
}
@Override
public int getTankCapacity(int tank) {
return 0;
}
@Override
public boolean isFluidValid(int tank, @Nonnull FluidStack stack) {
return false;
}
@Override
public int fill(FluidStack resource, FluidAction action) {
return 0;
}
@Override
public FluidStack drain(FluidStack resource, FluidAction action) {
return FluidStack.EMPTY;
}
@Override
public FluidStack drain(int maxDrain, FluidAction action) {
return FluidStack.EMPTY;
}
}
}
}

View file

@ -8,8 +8,9 @@
*/
package dev.zontreck.engineerdecor.blocks;
import com.mojang.blaze3d.vertex.PoseStack;
import dev.zontreck.engineerdecor.libmc.*;
import dev.zontreck.engineerdecor.ModContent;
import dev.zontreck.libzontreck.edlibmc.*;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
@ -32,7 +33,7 @@ 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.Level;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.SignalGetter;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.SoundType;
@ -54,8 +55,6 @@ import net.minecraftforge.common.util.FakePlayer;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fluids.IFluidBlock;
import net.minecraftforge.items.IItemHandler;
import dev.zontreck.engineerdecor.ModContent;
import wile.engineersdecor.libmc.*;
import javax.annotation.Nullable;
import java.util.ArrayList;
@ -63,45 +62,48 @@ import java.util.Arrays;
import java.util.List;
public class EdPlacer
{
public static void on_config()
{}
public class EdPlacer {
public static void on_config() {
}
//--------------------------------------------------------------------------------------------------------------------
// Block
//--------------------------------------------------------------------------------------------------------------------
public static class PlacerBlock extends StandardBlocks.Directed implements StandardEntityBlocks.IStandardEntityBlock<PlacerTileEntity>
{
public PlacerBlock(long config, BlockBehaviour.Properties builder, final AABB[] unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
public static class PlacerBlock extends StandardBlocks.Directed implements StandardEntityBlocks.IStandardEntityBlock<PlacerTileEntity> {
public PlacerBlock(long config, BlockBehaviour.Properties builder, final AABB[] unrotatedAABB) {
super(config, builder, unrotatedAABB);
}
@Override
public boolean isBlockEntityTicking(Level world, BlockState state)
{ return true; }
public boolean isBlockEntityTicking(Level world, BlockState state) {
return true;
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext)
{ return Shapes.block(); }
public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) {
return Shapes.block();
}
@Override
@SuppressWarnings("deprecation")
public boolean hasAnalogOutputSignal(BlockState state)
{ return true; }
public boolean hasAnalogOutputSignal(BlockState state) {
return true;
}
@Override
@SuppressWarnings("deprecation")
public int getAnalogOutputSignal(BlockState blockState, Level world, BlockPos pos)
{ return (world.getBlockEntity(pos) instanceof EdPlacer.PlacerTileEntity te) ? RsSignals.fromContainer(te.inventory_) : 0; }
public int getAnalogOutputSignal(BlockState blockState, Level world, BlockPos pos) {
return (world.getBlockEntity(pos) instanceof EdPlacer.PlacerTileEntity te) ? RsSignals.fromContainer(te.inventory_) : 0;
}
@Override
public boolean shouldCheckWeakPower(BlockState state, LevelReader world, BlockPos pos, Direction side)
{ return false; }
public boolean shouldCheckWeakPower(BlockState state, SignalGetter level, BlockPos pos, Direction side) {
return false;
}
@Override
public void setPlacedBy(Level world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack)
{
public void setPlacedBy(Level world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) {
if (world.isClientSide) return;
if ((!stack.hasTag()) || (!stack.getTag().contains("tedata"))) return;
CompoundTag te_nbt = stack.getTag().getCompound("tedata");
@ -113,12 +115,12 @@ public class EdPlacer
}
@Override
public boolean hasDynamicDropList()
{ return true; }
public boolean hasDynamicDropList() {
return true;
}
@Override
public List<ItemStack> dropList(BlockState state, Level world, final BlockEntity te, boolean explosion)
{
public List<ItemStack> dropList(BlockState state, Level world, final BlockEntity te, boolean explosion) {
final List<ItemStack> stacks = new ArrayList<>();
if (world.isClientSide) return stacks;
if (!(te instanceof PlacerTileEntity)) return stacks;
@ -142,13 +144,13 @@ public class EdPlacer
@Override
@SuppressWarnings("deprecation")
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult rayTraceResult)
{ return useOpenGui(state, world, pos, player); }
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult rayTraceResult) {
return useOpenGui(state, world, pos, player);
}
@Override
@SuppressWarnings("deprecation")
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block block, BlockPos fromPos, boolean unused)
{
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block block, BlockPos fromPos, boolean unused) {
if (!(world instanceof Level) || (world.isClientSide)) return;
BlockEntity te = world.getBlockEntity(pos);
if (!(te instanceof PlacerTileEntity)) return;
@ -157,26 +159,28 @@ public class EdPlacer
@Override
@SuppressWarnings("deprecation")
public boolean isSignalSource(BlockState state)
{ return true; }
public boolean isSignalSource(BlockState state) {
return true;
}
@Override
@SuppressWarnings("deprecation")
public int getSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side)
{ return 0; }
public int getSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side) {
return 0;
}
@Override
@SuppressWarnings("deprecation")
public int getDirectSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side)
{ return 0; }
public int getDirectSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side) {
return 0;
}
}
//--------------------------------------------------------------------------------------------------------------------
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
public static class PlacerTileEntity extends StandardEntityBlocks.StandardBlockEntity implements MenuProvider, Nameable
{
public static class PlacerTileEntity extends StandardEntityBlocks.StandardBlockEntity implements MenuProvider, Nameable {
public static final int TICK_INTERVAL = 40;
public static final int NUM_OF_SLOTS = 18;
public static final int NUM_OF_FIELDS = 3;
@ -184,18 +188,42 @@ public class EdPlacer
public static final int LOGIC_INVERTED = 0x01;
public static final int LOGIC_CONTINUOUS = 0x02;
public static final int LOGIC_IGNORE_EXT = 0x04;
private final boolean debug_ = false; // @todo debug stick in `self::use()` toggling.
private final Inventories.StorageInventory inventory_ = new Inventories.StorageInventory(this, NUM_OF_SLOTS, 1);
private final LazyOptional<IItemHandler> item_handler_;
///
private boolean block_power_signal_ = false;
private boolean block_power_updated_ = false;
private int logic_ = LOGIC_IGNORE_EXT | LOGIC_CONTINUOUS;
private int current_slot_index_ = 0;
private int tick_timer_ = 0;
private final boolean debug_ = false; // @todo debug stick in `self::use()` toggling.
private final Inventories.StorageInventory inventory_ = new Inventories.StorageInventory(this, NUM_OF_SLOTS, 1);
private final LazyOptional<IItemHandler> item_handler_;
protected final ContainerData fields = new ContainerData() {
@Override
public int getCount() {
return PlacerTileEntity.NUM_OF_FIELDS;
}
public PlacerTileEntity(BlockPos pos, BlockState state)
{
@Override
public int get(int id) {
return switch (id) {
case 0 -> logic_;
case 1 -> block_power_signal_ ? 1 : 0;
case 2 -> Mth.clamp(current_slot_index_, 0, NUM_OF_SLOTS - 1);
default -> 0;
};
}
@Override
public void set(int id, int value) {
switch (id) {
case 0 -> logic_ = value;
case 1 -> block_power_signal_ = (value != 0);
case 2 -> current_slot_index_ = Mth.clamp(value, 0, NUM_OF_SLOTS - 1);
}
}
};
private int tick_timer_ = 0;
public PlacerTileEntity(BlockPos pos, BlockState state) {
super(ModContent.getBlockEntityTypeOfBlock(state.getBlock()), pos, state);
item_handler_ = Inventories.MappedItemHandler.createGenericHandler(inventory_,
(stack, slot) -> true,
@ -203,8 +231,11 @@ public class EdPlacer
);
}
public CompoundTag clear_getnbt()
{
private static int next_slot(int i) {
return (i < NUM_OF_SLOTS - 1) ? (i + 1) : 0;
}
public CompoundTag clear_getnbt() {
CompoundTag nbt = new CompoundTag();
writenbt(nbt, false);
inventory_.clearContent();
@ -213,30 +244,28 @@ public class EdPlacer
return nbt;
}
public void reset_rtstate()
{
public void reset_rtstate() {
block_power_signal_ = false;
block_power_updated_ = false;
}
public void readnbt(CompoundTag nbt, boolean update_packet)
{
public void readnbt(CompoundTag nbt, boolean update_packet) {
inventory_.load(nbt);
block_power_signal_ = nbt.getBoolean("powered");
current_slot_index_ = nbt.getInt("act_slot_index");
logic_ = nbt.getInt("logic");
}
protected void writenbt(CompoundTag nbt, boolean update_packet)
{
// BlockEntity ------------------------------------------------------------------------------
protected void writenbt(CompoundTag nbt, boolean update_packet) {
inventory_.save(nbt);
nbt.putBoolean("powered", block_power_signal_);
nbt.putInt("act_slot_index", current_slot_index_);
nbt.putInt("logic", logic_);
}
public void block_updated()
{
public void block_updated() {
boolean powered = level.hasNeighborSignal(worldPosition);
if (block_power_signal_ != powered) block_power_updated_ = true;
block_power_signal_ = powered;
@ -247,95 +276,70 @@ public class EdPlacer
}
}
// BlockEntity ------------------------------------------------------------------------------
@Override
public void load(CompoundTag nbt)
{ super.load(nbt); readnbt(nbt, false); }
@Override
protected void saveAdditional(CompoundTag nbt)
{ super.saveAdditional(nbt); writenbt(nbt, false); }
@Override
public void setRemoved()
{
super.setRemoved();
item_handler_.invalidate();
public void load(CompoundTag nbt) {
super.load(nbt);
readnbt(nbt, false);
}
// Namable -----------------------------------------------------------------------------------------------
@Override
public Component getName()
{ return Auxiliaries.localizable(getBlockState().getBlock().getDescriptionId()); }
protected void saveAdditional(CompoundTag nbt) {
super.saveAdditional(nbt);
writenbt(nbt, false);
}
@Override
public boolean hasCustomName()
{ return false; }
public void setRemoved() {
super.setRemoved();
item_handler_.invalidate();
}
@Override
public Component getCustomName()
{ return getName(); }
public Component getName() {
return Auxiliaries.localizable(getBlockState().getBlock().getDescriptionId());
}
// INamedContainerProvider ------------------------------------------------------------------------------
@Override
public Component getDisplayName()
{ return Nameable.super.getDisplayName(); }
public boolean hasCustomName() {
return false;
}
@Override
public AbstractContainerMenu createMenu(int id, Inventory inventory, Player player )
{ return new PlacerContainer(id, inventory, inventory_, ContainerLevelAccess.create(level, worldPosition), fields); }
public Component getCustomName() {
return getName();
}
// Fields -----------------------------------------------------------------------------------------------
protected final ContainerData fields = new ContainerData()
{
@Override
public int getCount()
{ return PlacerTileEntity.NUM_OF_FIELDS; }
@Override
public int get(int id)
{
return switch (id) {
case 0 -> logic_;
case 1 -> block_power_signal_ ? 1 : 0;
case 2 -> Mth.clamp(current_slot_index_, 0, NUM_OF_SLOTS - 1);
default -> 0;
};
public Component getDisplayName() {
return Nameable.super.getDisplayName();
}
@Override
public void set(int id, int value)
{
switch (id) {
case 0 -> logic_ = value;
case 1 -> block_power_signal_ = (value != 0);
case 2 -> current_slot_index_ = Mth.clamp(value, 0, NUM_OF_SLOTS - 1);
}
}
};
// Capability export ------------------------------------------------------------------------------------
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
if(capability == ForgeCapabilities.ITEM_HANDLER) return item_handler_.cast();
return super.getCapability(capability, facing);
public AbstractContainerMenu createMenu(int id, Inventory inventory, Player player) {
return new PlacerContainer(id, inventory, inventory_, ContainerLevelAccess.create(level, worldPosition), fields);
}
// ITickable and aux methods ----------------------------------------------------------------------------
private static int next_slot(int i)
{ return (i<NUM_OF_SLOTS-1) ? (i+1) : 0; }
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing) {
if (capability == ForgeCapabilities.ITEM_HANDLER) return item_handler_.cast();
return super.getCapability(capability, facing);
}
private boolean spit_out(Direction facing)
{ return spit_out(facing, false); }
private boolean spit_out(Direction facing) {
return spit_out(facing, false);
}
private boolean spit_out(Direction facing, boolean all)
{
private boolean spit_out(Direction facing, boolean all) {
ItemStack stack = inventory_.getItem(current_slot_index_);
ItemStack drop = stack.copy();
if (!all) {
@ -355,8 +359,7 @@ public class EdPlacer
return true;
}
private boolean try_place(Direction facing, boolean triggered)
{
private boolean try_place(Direction facing, boolean triggered) {
if (level.isClientSide()) return false;
BlockPos placement_pos = worldPosition.relative(facing);
if (level.getBlockEntity(placement_pos) != null) return false;
@ -367,13 +370,17 @@ public class EdPlacer
if (!current_stack.isEmpty()) break;
current_slot_index_ = next_slot(current_slot_index_);
}
if(current_stack.isEmpty()) { current_slot_index_ = 0; return false; }
if (current_stack.isEmpty()) {
current_slot_index_ = 0;
return false;
}
boolean no_space = false;
final Item item = current_stack.getItem();
Block block = Block.byItem(item);
if (block == Blocks.AIR) {
if (item != null) {
if(debug_) Auxiliaries.logInfo("Placer spit: No block for item " + Auxiliaries.getResourceLocation(item));
if (debug_)
Auxiliaries.logInfo("Placer spit: No block for item " + Auxiliaries.getResourceLocation(item));
return spit_out(facing); // Item not accepted
}
} else if (block instanceof IPlantable) {
@ -404,19 +411,20 @@ public class EdPlacer
}
} else {
final BlockState current_placement_pos_state = level.getBlockState(placement_pos);
@SuppressWarnings("deprecation")
final boolean replacable = (current_placement_pos_state.getBlock().canBeReplaced(current_placement_pos_state, Fluids.EMPTY)) && (
@SuppressWarnings("deprecation") final boolean replacable = (current_placement_pos_state.getBlock().canBeReplaced(current_placement_pos_state, Fluids.EMPTY)) && (
level.isEmptyBlock(placement_pos) ||
(current_placement_pos_state.getBlock() instanceof IFluidBlock) ||
(current_placement_pos_state.getMaterial().isReplaceable() && (!current_placement_pos_state.getMaterial().isSolid()))
(current_placement_pos_state.canBeReplaced() && (!current_placement_pos_state.isAir()))
);
if ((!replacable) || (
(!level.getEntitiesOfClass(Entity.class, new AABB(placement_pos), (Entity e) -> {
if (e.isPickable()) return true;
if (triggered) return false;
if ((e instanceof ItemEntity)) {
if((e.getDeltaMovement().y() > 0) || (e.getDeltaMovement().y() < -0.5)) return true; // not falling or falling by
if(Math.abs(e.getDeltaMovement().x())+Math.abs(e.getDeltaMovement().z()) > 0) return true; // not straight
if ((e.getDeltaMovement().y() > 0) || (e.getDeltaMovement().y() < -0.5))
return true; // not falling or falling by
if (Math.abs(e.getDeltaMovement().x()) + Math.abs(e.getDeltaMovement().z()) > 0)
return true; // not straight
}
return false;
}).isEmpty())
@ -449,22 +457,26 @@ public class EdPlacer
}
BlockState placement_state = (use_context == null) ? (block.defaultBlockState()) : (block.getStateForPlacement(use_context));
if (placement_state == null) {
if(debug_) Auxiliaries.logInfo("Placer spit: No valid placement state for item " + Auxiliaries.getResourceLocation(item));
if (debug_)
Auxiliaries.logInfo("Placer spit: No valid placement state for item " + Auxiliaries.getResourceLocation(item));
return spit_out(facing);
} else if ((use_context != null) && (item instanceof BlockItem)) {
if (((BlockItem) item).place(use_context) != InteractionResult.FAIL) {
SoundType stype = block.getSoundType(placement_state, level, worldPosition, null);
if(stype != null) level.playSound(null, placement_pos, stype.getPlaceSound(), SoundSource.BLOCKS, stype.getVolume()*0.6f, stype.getPitch());
if (stype != null)
level.playSound(null, placement_pos, stype.getPlaceSound(), SoundSource.BLOCKS, stype.getVolume() * 0.6f, stype.getPitch());
} else {
if (level.setBlock(placement_pos, placement_state, 1 | 2 | 8)) {
SoundType stype = block.getSoundType(placement_state, level, worldPosition, null);
if(stype != null) level.playSound(null, placement_pos, stype.getPlaceSound(), SoundSource.BLOCKS, stype.getVolume()*0.6f, stype.getPitch());
if (stype != null)
level.playSound(null, placement_pos, stype.getPlaceSound(), SoundSource.BLOCKS, stype.getVolume() * 0.6f, stype.getPitch());
}
}
} else {
if (level.setBlock(placement_pos, placement_state, 1 | 2 | 8)) {
SoundType stype = block.getSoundType(placement_state, level, worldPosition, null);
if(stype != null) level.playSound(null, placement_pos, stype.getPlaceSound(), SoundSource.BLOCKS, stype.getVolume()*0.6f, stype.getPitch());
if (stype != null)
level.playSound(null, placement_pos, stype.getPlaceSound(), SoundSource.BLOCKS, stype.getVolume() * 0.6f, stype.getPitch());
}
}
current_stack.shrink(1);
@ -494,15 +506,17 @@ public class EdPlacer
}
@Override
public void tick()
{
public void tick() {
// Tick cycle pre-conditions
if (level.isClientSide) return;
if (--tick_timer_ > 0) return;
tick_timer_ = TICK_INTERVAL;
// Cycle init
final BlockState state = level.getBlockState(worldPosition);
if(!(state.getBlock() instanceof PlacerBlock)) { block_power_signal_= false; return; }
if (!(state.getBlock() instanceof PlacerBlock)) {
block_power_signal_ = false;
return;
}
final boolean updated = block_power_updated_;
final boolean rssignal = ((logic_ & LOGIC_IGNORE_EXT) != 0) || ((logic_ & LOGIC_INVERTED) != 0) == (!block_power_signal_);
final boolean trigger = ((logic_ & LOGIC_IGNORE_EXT) != 0) || (rssignal && ((updated) || ((logic_ & LOGIC_CONTINUOUS) != 0)));
@ -526,8 +540,7 @@ public class EdPlacer
// Container
//--------------------------------------------------------------------------------------------------------------------
public static class PlacerContainer extends AbstractContainerMenu implements Networking.INetworkSynchronisableContainer
{
public static class PlacerContainer extends AbstractContainerMenu implements Networking.INetworkSynchronisableContainer {
protected static final String QUICK_MOVE_ALL = "quick-move-all";
private static final int PLAYER_INV_START_SLOTNO = PlacerTileEntity.NUM_OF_SLOTS;
private final Player player_;
@ -537,13 +550,11 @@ public class EdPlacer
private final Inventories.InventoryRange player_inventory_range_;
private final Inventories.InventoryRange block_storage_range_;
public final int field(int index) { return fields_.get(index); }
public PlacerContainer(int cid, Inventory player_inventory) {
this(cid, player_inventory, new SimpleContainer(PlacerTileEntity.NUM_OF_SLOTS), ContainerLevelAccess.NULL, new SimpleContainerData(PlacerTileEntity.NUM_OF_FIELDS));
}
public PlacerContainer(int cid, Inventory player_inventory)
{ this(cid, player_inventory, new SimpleContainer(PlacerTileEntity.NUM_OF_SLOTS), ContainerLevelAccess.NULL, new SimpleContainerData(PlacerTileEntity.NUM_OF_FIELDS)); }
private PlacerContainer(int cid, Inventory player_inventory, Container block_inventory, ContainerLevelAccess wpc, ContainerData fields)
{
private PlacerContainer(int cid, Inventory player_inventory, Container block_inventory, ContainerLevelAccess wpc, ContainerData fields) {
super(ModContent.getMenuType("factory_placer"), cid); // @todo: class mapping
fields_ = fields;
wpc_ = wpc;
@ -571,20 +582,25 @@ public class EdPlacer
this.addDataSlots(fields_); // === Add reference holders
}
@Override
public boolean stillValid(Player player)
{ return inventory_.stillValid(player); }
public final int field(int index) {
return fields_.get(index);
}
@Override
public ItemStack quickMoveStack(Player player, int index)
{
public boolean stillValid(Player player) {
return inventory_.stillValid(player);
}
@Override
public ItemStack quickMoveStack(Player player, int index) {
Slot slot = getSlot(index);
if ((slot == null) || (!slot.hasItem())) return ItemStack.EMPTY;
ItemStack slot_stack = slot.getItem();
ItemStack transferred = slot_stack.copy();
if ((index >= 0) && (index < PLAYER_INV_START_SLOTNO)) {
// Device slots
if(!moveItemStackTo(slot_stack, PLAYER_INV_START_SLOTNO, PLAYER_INV_START_SLOTNO+36, false)) return ItemStack.EMPTY;
if (!moveItemStackTo(slot_stack, PLAYER_INV_START_SLOTNO, PLAYER_INV_START_SLOTNO + 36, false))
return ItemStack.EMPTY;
} else if ((index >= PLAYER_INV_START_SLOTNO) && (index <= PLAYER_INV_START_SLOTNO + 36)) {
// Player slot
if (!moveItemStackTo(slot_stack, 0, PlacerTileEntity.NUM_OF_SLOTS, false)) return ItemStack.EMPTY;
@ -605,33 +621,32 @@ public class EdPlacer
// INetworkSynchronisableContainer ---------------------------------------------------------
@OnlyIn(Dist.CLIENT)
public void onGuiAction(CompoundTag nbt)
{ Networking.PacketContainerSyncClientToServer.sendToServer(containerId, nbt); }
public void onGuiAction(CompoundTag nbt) {
Networking.PacketContainerSyncClientToServer.sendToServer(containerId, nbt);
}
@OnlyIn(Dist.CLIENT)
public void onGuiAction(String key, int value)
{
public void onGuiAction(String key, int value) {
CompoundTag nbt = new CompoundTag();
nbt.putInt(key, value);
Networking.PacketContainerSyncClientToServer.sendToServer(containerId, nbt);
}
@OnlyIn(Dist.CLIENT)
public void onGuiAction(String message, CompoundTag nbt)
{
public void onGuiAction(String message, CompoundTag nbt) {
nbt.putString("action", message);
Networking.PacketContainerSyncClientToServer.sendToServer(containerId, nbt);
}
@Override
public void onServerPacketReceived(int windowId, CompoundTag nbt)
{}
public void onServerPacketReceived(int windowId, CompoundTag nbt) {
}
@Override
public void onClientPacketReceived(int windowId, Player player, CompoundTag nbt)
{
public void onClientPacketReceived(int windowId, Player player, CompoundTag nbt) {
if (!(inventory_ instanceof Inventories.StorageInventory)) return;
if(!((((Inventories.StorageInventory)inventory_).getBlockEntity()) instanceof PlacerTileEntity te)) return;
if (!((((Inventories.StorageInventory) inventory_).getBlockEntity()) instanceof PlacerTileEntity te))
return;
if (nbt.contains("action")) {
final int slotId = nbt.contains("slot") ? nbt.getInt("slot") : -1;
boolean changed = false;
@ -651,7 +666,11 @@ public class EdPlacer
}
} else {
if (nbt.contains("logic")) te.logic_ = nbt.getInt("logic");
if(nbt.contains("manual_trigger") && (nbt.getInt("manual_trigger")!=0)) { te.block_power_signal_=true; te.block_power_updated_=true; te.tick_timer_=1; }
if (nbt.contains("manual_trigger") && (nbt.getInt("manual_trigger") != 0)) {
te.block_power_signal_ = true;
te.block_power_updated_ = true;
te.tick_timer_ = 1;
}
te.setChanged();
}
@ -663,14 +682,13 @@ public class EdPlacer
//--------------------------------------------------------------------------------------------------------------------
@OnlyIn(Dist.CLIENT)
public static class PlacerGui extends Guis.ContainerGui<PlacerContainer>
{
public PlacerGui(PlacerContainer container, Inventory player_inventory, Component title)
{ super(container, player_inventory, title,"textures/gui/factory_placer_gui.png"); }
public static class PlacerGui extends Guis.ContainerGui<PlacerContainer> {
public PlacerGui(PlacerContainer container, Inventory player_inventory, Component title) {
super(container, player_inventory, title, "textures/gui/factory_placer_gui.png");
}
@Override
public void init()
{
public void init() {
super.init();
{
final Block block = ModContent.getBlock(Auxiliaries.getResourceLocation(getMenu().getType()).getPath().replaceAll("^ct_", ""));
@ -685,8 +703,7 @@ public class EdPlacer
}
@Override
public boolean mouseClicked(double mouseX, double mouseY, int mouseButton)
{
public boolean mouseClicked(double mouseX, double mouseY, int mouseButton) {
tooltip_.resetTimer();
PlacerContainer container = getMenu();
int mx = (int) (mouseX - getGuiLeft() + .5), my = (int) (mouseY - getGuiTop() + .5);
@ -710,8 +727,7 @@ public class EdPlacer
}
@Override
protected void slotClicked(Slot slot, int slotId, int button, ClickType type)
{
protected void slotClicked(Slot slot, int slotId, int button, ClickType type) {
tooltip_.resetTimer();
if ((type == ClickType.QUICK_MOVE) && (slot != null) && slot.hasItem() && Auxiliaries.isShiftDown() && Auxiliaries.isCtrlDown()) {
CompoundTag nbt = new CompoundTag();
@ -723,8 +739,7 @@ public class EdPlacer
}
@Override
protected void renderBgWidgets(PoseStack mx, float partialTicks, int mouseX, int mouseY)
{
protected void renderBgWidgets(GuiGraphics mx, float partialTicks, int mouseX, int mouseY) {
final int x0 = getGuiLeft(), y0 = getGuiTop(), w = getXSize(), h = getYSize();
PlacerContainer container = getMenu();
// active slot
@ -733,21 +748,21 @@ public class EdPlacer
if ((slot_index < 0) || (slot_index >= PlacerTileEntity.NUM_OF_SLOTS)) slot_index = 0;
int x = (x0 + 10 + ((slot_index % 6) * 18));
int y = (y0 + 8 + ((slot_index / 6) * 17));
blit(mx, x, y, 200, 8, 18, 18);
mx.blit(getBackgroundImage(), x, y, 200, 8, 18, 18);
}
// redstone input
{
if (container.field(1) != 0) {
blit(mx, x0+133, y0+49, 217, 49, 9, 9);
mx.blit(getBackgroundImage(), x0 + 133, y0 + 49, 217, 49, 9, 9);
}
}
// trigger logic
{
int inverter_offset_x = ((container.field(0) & PlacerTileEntity.LOGIC_INVERTED) != 0) ? 11 : 0;
int inverter_offset_y = ((container.field(0) & PlacerTileEntity.LOGIC_IGNORE_EXT) != 0) ? 10 : 0;
blit(mx, x0+145, y0+49, 177+inverter_offset_x, 49+inverter_offset_y, 9, 9);
mx.blit(getBackgroundImage(), x0 + 145, y0 + 49, 177 + inverter_offset_x, 49 + inverter_offset_y, 9, 9);
int pulse_mode_offset = ((container.field(0) & PlacerTileEntity.LOGIC_CONTINUOUS) != 0) ? 9 : 0;
blit(mx, x0+159, y0+49, 199+pulse_mode_offset, 49, 9, 9);
mx.blit(getBackgroundImage(), x0 + 159, y0 + 49, 199 + pulse_mode_offset, 49, 9, 9);
}
}
}

View file

@ -8,6 +8,8 @@
*/
package dev.zontreck.engineerdecor.blocks;
import dev.zontreck.libzontreck.edlibmc.Auxiliaries;
import dev.zontreck.libzontreck.edlibmc.StandardBlocks;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.item.context.BlockPlaceContext;
@ -33,119 +35,33 @@ 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 dev.zontreck.engineerdecor.libmc.StandardBlocks;
import dev.zontreck.engineerdecor.libmc.Auxiliaries;
public class EdRoofBlock extends StandardBlocks.HorizontalWaterLoggable
{
public class EdRoofBlock extends StandardBlocks.HorizontalWaterLoggable {
public static final EnumProperty<StairsShape> SHAPE = BlockStateProperties.STAIRS_SHAPE;
public static final EnumProperty<Half> HALF = BlockStateProperties.HALF;
private final VoxelShape[][][] shape_cache_;
public EdRoofBlock(long config, BlockBehaviour.Properties properties)
{ this(config, properties.dynamicShape(), Shapes.empty(), Shapes.empty()); }
public EdRoofBlock(long config, BlockBehaviour.Properties properties) {
this(config, properties.dynamicShape(), Shapes.empty(), Shapes.empty());
}
public EdRoofBlock(long config, BlockBehaviour.Properties properties, VoxelShape add, VoxelShape cut)
{
public EdRoofBlock(long config, BlockBehaviour.Properties properties, VoxelShape add, VoxelShape cut) {
super(config, properties, Auxiliaries.getPixeledAABB(0, 0, 0, 16, 8, 16));
registerDefaultState(super.defaultBlockState().setValue(HORIZONTAL_FACING, Direction.NORTH).setValue(SHAPE, StairsShape.STRAIGHT));
shape_cache_ = makeShapes(add, cut);
}
@Override
@SuppressWarnings("deprecation")
public boolean useShapeForLightOcclusion(BlockState state)
{ return false; }
@OnlyIn(Dist.CLIENT)
@SuppressWarnings("deprecation")
public float getShadeBrightness(BlockState state, BlockGetter world, BlockPos pos)
{ return 0.98f; }
@Override
@SuppressWarnings("deprecation")
public int getLightBlock(BlockState state, BlockGetter world, BlockPos pos)
{ return 1; }
@Override
public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context)
{ return shape_cache_[state.getValue(HALF).ordinal()][state.getValue(HORIZONTAL_FACING).get3DDataValue()][state.getValue(SHAPE).ordinal()]; }
@Override
public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext)
{ return getShape(state, world, pos, selectionContext); }
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder)
{ super.createBlockStateDefinition(builder); builder.add(SHAPE, HALF); }
@Override
public FluidState getFluidState(BlockState state)
{ return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(state); }
@Override
public boolean isPathfindable(BlockState state, BlockGetter world, BlockPos pos, PathComputationType type)
{ return false; }
@Override
public BlockState getStateForPlacement(BlockPlaceContext context)
{
BlockPos pos = context.getClickedPos();
Direction face = context.getClickedFace();
BlockState state = defaultBlockState()
.setValue(HORIZONTAL_FACING, context.getHorizontalDirection())
.setValue(HALF, (face == Direction.DOWN) ? Half.TOP : Half.BOTTOM)
.setValue(WATERLOGGED, context.getLevel().getFluidState(pos).getType()==Fluids.WATER);
return state.setValue(SHAPE, getStairsShapeProperty(state, context.getLevel(), pos));
private static boolean isRoofBlock(BlockState state) {
return (state.getBlock() instanceof EdRoofBlock);
}
@Override
public BlockState updateShape(BlockState state, Direction facing, BlockState facingState, LevelAccessor world, BlockPos pos, BlockPos facingPos)
{
if(state.getValue(WATERLOGGED)) world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world));
return (facing.getAxis().isHorizontal()) ? (state.setValue(SHAPE, getStairsShapeProperty(state, world, pos))) : (super.updateShape(state, facing, facingState, world, pos, facingPos));
}
@Override
public BlockState rotate(BlockState state, Rotation rot)
{ return state.setValue(HORIZONTAL_FACING, rot.rotate(state.getValue(HORIZONTAL_FACING))); }
@Override
@SuppressWarnings("deprecation")
public BlockState mirror(BlockState state, Mirror where)
{
if((where==Mirror.LEFT_RIGHT) && (state.getValue(HORIZONTAL_FACING).getAxis()==Direction.Axis.Z)) {
return switch (state.getValue(SHAPE)) {
case INNER_LEFT -> state.rotate(Rotation.CLOCKWISE_180).setValue(SHAPE, StairsShape.INNER_RIGHT);
case INNER_RIGHT -> state.rotate(Rotation.CLOCKWISE_180).setValue(SHAPE, StairsShape.INNER_LEFT);
case OUTER_LEFT -> state.rotate(Rotation.CLOCKWISE_180).setValue(SHAPE, StairsShape.OUTER_RIGHT);
case OUTER_RIGHT -> state.rotate(Rotation.CLOCKWISE_180).setValue(SHAPE, StairsShape.OUTER_LEFT);
default -> state.rotate(Rotation.CLOCKWISE_180);
};
} else if((where==Mirror.FRONT_BACK) && (state.getValue(HORIZONTAL_FACING).getAxis() == Direction.Axis.X)) {
return switch (state.getValue(SHAPE)) {
case INNER_LEFT -> state.rotate(Rotation.CLOCKWISE_180).setValue(SHAPE, StairsShape.INNER_LEFT);
case INNER_RIGHT -> state.rotate(Rotation.CLOCKWISE_180).setValue(SHAPE, StairsShape.INNER_RIGHT);
case OUTER_LEFT -> state.rotate(Rotation.CLOCKWISE_180).setValue(SHAPE, StairsShape.OUTER_RIGHT);
case OUTER_RIGHT -> state.rotate(Rotation.CLOCKWISE_180).setValue(SHAPE, StairsShape.OUTER_LEFT);
case STRAIGHT -> state.rotate(Rotation.CLOCKWISE_180);
};
}
return super.mirror(state, where);
}
private static boolean isRoofBlock(BlockState state)
{ return (state.getBlock() instanceof EdRoofBlock); }
private static boolean isOtherRoofState(BlockState state, BlockGetter world, BlockPos pos, Direction facing)
{
private static boolean isOtherRoofState(BlockState state, BlockGetter world, BlockPos pos, Direction facing) {
BlockState st = world.getBlockState(pos.relative(facing));
return (!isRoofBlock(st)) || (st.getValue(HORIZONTAL_FACING) != state.getValue(HORIZONTAL_FACING));
}
private static VoxelShape[][][] makeShapes(VoxelShape add, VoxelShape cut)
{
private static VoxelShape[][][] makeShapes(VoxelShape add, VoxelShape cut) {
VoxelShape[][][] shapes = new VoxelShape[2][6][5];
for (int half_index = 0; half_index < Half.values().length; ++half_index) {
for (int direction_index = 0; direction_index < Direction.values().length; ++direction_index) {
@ -166,8 +82,7 @@ public class EdRoofBlock extends StandardBlocks.HorizontalWaterLoggable
return shapes;
}
private static VoxelShape makeShape(int half_index, int direction_index, int stairs_shape_index)
{
private static VoxelShape makeShape(int half_index, int direction_index, int stairs_shape_index) {
AABB[] straight = new AABB[]{
Auxiliaries.getPixeledAABB(0, 0, 0, 16, 4, 16),
Auxiliaries.getPixeledAABB(4, 4, 0, 16, 8, 16),
@ -204,8 +119,7 @@ public class EdRoofBlock extends StandardBlocks.HorizontalWaterLoggable
};
}
private static StairsShape getStairsShapeProperty(BlockState state, BlockGetter world, BlockPos pos)
{
private static StairsShape getStairsShapeProperty(BlockState state, BlockGetter world, BlockPos pos) {
Direction direction = state.getValue(HORIZONTAL_FACING);
{
BlockState ns = world.getBlockState(pos.relative(direction));
@ -227,4 +141,93 @@ public class EdRoofBlock extends StandardBlocks.HorizontalWaterLoggable
}
return StairsShape.STRAIGHT;
}
@Override
@SuppressWarnings("deprecation")
public boolean useShapeForLightOcclusion(BlockState state) {
return false;
}
@OnlyIn(Dist.CLIENT)
@SuppressWarnings("deprecation")
public float getShadeBrightness(BlockState state, BlockGetter world, BlockPos pos) {
return 0.98f;
}
@Override
@SuppressWarnings("deprecation")
public int getLightBlock(BlockState state, BlockGetter world, BlockPos pos) {
return 1;
}
@Override
public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) {
return shape_cache_[state.getValue(HALF).ordinal()][state.getValue(HORIZONTAL_FACING).get3DDataValue()][state.getValue(SHAPE).ordinal()];
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) {
return getShape(state, world, pos, selectionContext);
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
super.createBlockStateDefinition(builder);
builder.add(SHAPE, HALF);
}
@Override
public FluidState getFluidState(BlockState state) {
return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(state);
}
@Override
public boolean isPathfindable(BlockState state, BlockGetter world, BlockPos pos, PathComputationType type) {
return false;
}
@Override
public BlockState getStateForPlacement(BlockPlaceContext context) {
BlockPos pos = context.getClickedPos();
Direction face = context.getClickedFace();
BlockState state = defaultBlockState()
.setValue(HORIZONTAL_FACING, context.getHorizontalDirection())
.setValue(HALF, (face == Direction.DOWN) ? Half.TOP : Half.BOTTOM)
.setValue(WATERLOGGED, context.getLevel().getFluidState(pos).getType() == Fluids.WATER);
return state.setValue(SHAPE, getStairsShapeProperty(state, context.getLevel(), pos));
}
@Override
public BlockState updateShape(BlockState state, Direction facing, BlockState facingState, LevelAccessor world, BlockPos pos, BlockPos facingPos) {
if (state.getValue(WATERLOGGED)) world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world));
return (facing.getAxis().isHorizontal()) ? (state.setValue(SHAPE, getStairsShapeProperty(state, world, pos))) : (super.updateShape(state, facing, facingState, world, pos, facingPos));
}
@Override
public BlockState rotate(BlockState state, Rotation rot) {
return state.setValue(HORIZONTAL_FACING, rot.rotate(state.getValue(HORIZONTAL_FACING)));
}
@Override
@SuppressWarnings("deprecation")
public BlockState mirror(BlockState state, Mirror where) {
if ((where == Mirror.LEFT_RIGHT) && (state.getValue(HORIZONTAL_FACING).getAxis() == Direction.Axis.Z)) {
return switch (state.getValue(SHAPE)) {
case INNER_LEFT -> state.rotate(Rotation.CLOCKWISE_180).setValue(SHAPE, StairsShape.INNER_RIGHT);
case INNER_RIGHT -> state.rotate(Rotation.CLOCKWISE_180).setValue(SHAPE, StairsShape.INNER_LEFT);
case OUTER_LEFT -> state.rotate(Rotation.CLOCKWISE_180).setValue(SHAPE, StairsShape.OUTER_RIGHT);
case OUTER_RIGHT -> state.rotate(Rotation.CLOCKWISE_180).setValue(SHAPE, StairsShape.OUTER_LEFT);
default -> state.rotate(Rotation.CLOCKWISE_180);
};
} else if ((where == Mirror.FRONT_BACK) && (state.getValue(HORIZONTAL_FACING).getAxis() == Direction.Axis.X)) {
return switch (state.getValue(SHAPE)) {
case INNER_LEFT -> state.rotate(Rotation.CLOCKWISE_180).setValue(SHAPE, StairsShape.INNER_LEFT);
case INNER_RIGHT -> state.rotate(Rotation.CLOCKWISE_180).setValue(SHAPE, StairsShape.INNER_RIGHT);
case OUTER_LEFT -> state.rotate(Rotation.CLOCKWISE_180).setValue(SHAPE, StairsShape.OUTER_RIGHT);
case OUTER_RIGHT -> state.rotate(Rotation.CLOCKWISE_180).setValue(SHAPE, StairsShape.OUTER_LEFT);
case STRAIGHT -> state.rotate(Rotation.CLOCKWISE_180);
};
}
return super.mirror(state, where);
}
}

View file

@ -8,6 +8,9 @@
*/
package dev.zontreck.engineerdecor.blocks;
import dev.zontreck.engineerdecor.ModConfig;
import dev.zontreck.engineerdecor.ModContent;
import dev.zontreck.libzontreck.edlibmc.*;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
@ -16,8 +19,8 @@ import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.LightLayer;
import net.minecraft.world.level.SignalGetter;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockBehaviour;
@ -29,20 +32,12 @@ import net.minecraft.world.phys.BlockHitResult;
import net.minecraftforge.common.capabilities.ForgeCapabilities;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.energy.IEnergyStorage;
import dev.zontreck.engineerdecor.ModConfig;
import dev.zontreck.engineerdecor.ModContent;
import dev.zontreck.engineerdecor.libmc.StandardBlocks;
import dev.zontreck.engineerdecor.libmc.StandardEntityBlocks;
import dev.zontreck.engineerdecor.libmc.Auxiliaries;
import dev.zontreck.engineerdecor.libmc.Overlay;
import dev.zontreck.engineerdecor.libmc.RfEnergy;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
public class EdSolarPanel
{
public class EdSolarPanel {
public static final int DEFAULT_PEAK_POWER = 40;
private static int peak_power_per_tick_ = DEFAULT_PEAK_POWER;
private static int max_power_storage_ = 64000;
@ -50,8 +45,7 @@ public class EdSolarPanel
private static int feeding_threshold = max_power_storage_ / 5;
private static int balancing_threshold = max_power_storage_ / 10;
public static void on_config(int peak_power_per_tick, int battery_capacity, int max_feed_in_power)
{
public static void on_config(int peak_power_per_tick, int battery_capacity, int max_feed_in_power) {
final int t = SolarPanelTileEntity.TICK_INTERVAL;
peak_power_per_tick_ = Mth.clamp(peak_power_per_tick, 12, 8192);
feeding_threshold = Math.max(max_power_storage_ / 5, 1000);
@ -65,28 +59,28 @@ public class EdSolarPanel
// Block
//--------------------------------------------------------------------------------------------------------------------
public static class SolarPanelBlock extends StandardBlocks.Cutout implements StandardEntityBlocks.IStandardEntityBlock<SolarPanelTileEntity>
{
public static class SolarPanelBlock extends StandardBlocks.Cutout implements StandardEntityBlocks.IStandardEntityBlock<SolarPanelTileEntity> {
public static final IntegerProperty EXPOSITION = IntegerProperty.create("exposition", 0, 4);
public SolarPanelBlock(long config, BlockBehaviour.Properties builder, final AABB[] unrotatedAABB)
{
public SolarPanelBlock(long config, BlockBehaviour.Properties builder, final AABB[] unrotatedAABB) {
super(config, builder, unrotatedAABB);
registerDefaultState(super.defaultBlockState().setValue(EXPOSITION, 1));
}
@Override
public boolean isBlockEntityTicking(Level world, BlockState state)
{ return true; }
public boolean isBlockEntityTicking(Level world, BlockState state) {
return true;
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder)
{ super.createBlockStateDefinition(builder); builder.add(EXPOSITION); }
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
super.createBlockStateDefinition(builder);
builder.add(EXPOSITION);
}
@Override
@SuppressWarnings("deprecation")
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit)
{
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
if (world.isClientSide()) return InteractionResult.SUCCESS;
BlockEntity te = world.getBlockEntity(pos);
if (te instanceof SolarPanelTileEntity) ((SolarPanelTileEntity) te).state_message(player);
@ -94,42 +88,42 @@ public class EdSolarPanel
}
@Override
public boolean shouldCheckWeakPower(BlockState state, LevelReader world, BlockPos pos, Direction side)
{ return false; }
public boolean shouldCheckWeakPower(BlockState state, SignalGetter level, BlockPos pos, Direction side) {
return false;
}
}
//--------------------------------------------------------------------------------------------------------------------
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
public static class SolarPanelTileEntity extends StandardEntityBlocks.StandardBlockEntity
{
public static class SolarPanelTileEntity extends StandardEntityBlocks.StandardBlockEntity {
public static final int TICK_INTERVAL = 4;
public static final int ACCUMULATION_INTERVAL = 8;
private static final Direction[] transfer_directions_ = {Direction.DOWN, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.NORTH};
private final RfEnergy.Battery battery_ = new RfEnergy.Battery(max_power_storage_, 0, 1024);
private final LazyOptional<IEnergyStorage> energy_handler_ = battery_.createEnergyHandler();
private int tick_timer_ = 0;
private int recalc_timer_ = 0;
private int current_production_ = 0;
private int current_feedin_ = 0;
private boolean output_enabled_ = false;
private final RfEnergy.Battery battery_ = new RfEnergy.Battery(max_power_storage_, 0, 1024);
private final LazyOptional<IEnergyStorage> energy_handler_ = battery_.createEnergyHandler();
//------------------------------------------------------------------------------------------------------------------
public SolarPanelTileEntity(BlockPos pos, BlockState state)
{ super(ModContent.getBlockEntityTypeOfBlock(state.getBlock()), pos, state); }
public SolarPanelTileEntity(BlockPos pos, BlockState state) {
super(ModContent.getBlockEntityTypeOfBlock(state.getBlock()), pos, state);
}
public void readnbt(CompoundTag nbt, boolean update_packet)
{ battery_.load(nbt); }
public void readnbt(CompoundTag nbt, boolean update_packet) {
battery_.load(nbt);
}
protected void writenbt(CompoundTag nbt, boolean update_packet)
{ battery_.save(nbt); }
protected void writenbt(CompoundTag nbt, boolean update_packet) {
battery_.save(nbt);
}
public void state_message(Player player)
{
public void state_message(Player player) {
String soc = Integer.toString(Mth.clamp((battery_.getEnergyStored() * 100 / max_power_storage_), 0, 100));
Overlay.show(player, Auxiliaries.localizable("block.engineersdecor.small_solar_panel.status", soc, max_power_storage_, current_production_, current_feedin_));
}
@ -137,8 +131,7 @@ public class EdSolarPanel
// ICapabilityProvider ---------------------------------------------------------------------
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing) {
if (capability == ForgeCapabilities.ENERGY) return energy_handler_.cast();
return super.getCapability(capability, facing);
}
@ -146,23 +139,25 @@ public class EdSolarPanel
// BlockEntity ------------------------------------------------------------------------------
@Override
public void load(CompoundTag nbt)
{ super.load(nbt); readnbt(nbt, false); }
public void load(CompoundTag nbt) {
super.load(nbt);
readnbt(nbt, false);
}
@Override
protected void saveAdditional(CompoundTag nbt)
{ super.saveAdditional(nbt); writenbt(nbt, false); }
protected void saveAdditional(CompoundTag nbt) {
super.saveAdditional(nbt);
writenbt(nbt, false);
}
@Override
public void setRemoved()
{
public void setRemoved() {
super.setRemoved();
energy_handler_.invalidate();
}
@Override
public void tick()
{
public void tick() {
if ((level.isClientSide) || (--tick_timer_ > 0)) return;
tick_timer_ = TICK_INTERVAL;
BlockState state = level.getBlockState(worldPosition);
@ -190,7 +185,8 @@ public class EdSolarPanel
current_feedin_ /= TICK_INTERVAL;
if ((current_feedin_ <= 0) && ((battery_.getEnergyStored() >= balancing_threshold) || (current_production_ <= 0))) {
for (SolarPanelTileEntity panel : adjacent_panels) {
if(panel.battery_.getEnergyStored() >= (battery_.getEnergyStored()-balancing_threshold)) continue;
if (panel.battery_.getEnergyStored() >= (battery_.getEnergyStored() - balancing_threshold))
continue;
panel.battery_.setEnergyStored(panel.battery_.getEnergyStored() + balancing_threshold);
battery_.setEnergyStored(battery_.getEnergyStored() - balancing_threshold);
if (battery_.getEnergyStored() < balancing_threshold) break;
@ -200,7 +196,8 @@ public class EdSolarPanel
tick_timer_ = TICK_INTERVAL * 10;
current_production_ = 0;
if ((!battery_.isEmpty())) output_enabled_ = true;
if(state.getValue((SolarPanelBlock.EXPOSITION))!=2) level.setBlockAndUpdate(worldPosition, state.setValue(SolarPanelBlock.EXPOSITION, 2));
if (state.getValue((SolarPanelBlock.EXPOSITION)) != 2)
level.setBlockAndUpdate(worldPosition, state.setValue(SolarPanelBlock.EXPOSITION, 2));
return;
}
if (battery_.isEmpty()) output_enabled_ = false;

View file

@ -8,6 +8,8 @@
*/
package dev.zontreck.engineerdecor.blocks;
import dev.zontreck.libzontreck.edlibmc.Inventories;
import dev.zontreck.libzontreck.edlibmc.StandardBlocks;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.sounds.SoundEvents;
@ -26,24 +28,22 @@ import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
import dev.zontreck.engineerdecor.libmc.StandardBlocks;
import dev.zontreck.engineerdecor.libmc.Inventories;
import javax.annotation.Nullable;
import java.util.Arrays;
public class EdStraightPoleBlock extends StandardBlocks.DirectedWaterLoggable
{
public class EdStraightPoleBlock extends StandardBlocks.DirectedWaterLoggable {
private final EdStraightPoleBlock default_pole;
public EdStraightPoleBlock(long config, BlockBehaviour.Properties builder, final AABB unrotatedAABB, @Nullable EdStraightPoleBlock defaultPole)
{ super(config, builder, unrotatedAABB); default_pole=(defaultPole==null) ? (this) : (defaultPole); }
public EdStraightPoleBlock(long config, BlockBehaviour.Properties builder, final AABB unrotatedAABB, @Nullable EdStraightPoleBlock defaultPole) {
super(config, builder, unrotatedAABB);
default_pole = (defaultPole == null) ? (this) : (defaultPole);
}
@Override
@Nullable
public BlockState getStateForPlacement(BlockPlaceContext context)
{
public BlockState getStateForPlacement(BlockPlaceContext context) {
Direction facing = context.getClickedFace();
BlockState state = super.getStateForPlacement(context).setValue(FACING, facing);
if ((config & StandardBlocks.CFG_FLIP_PLACEMENT_IF_SAME) != 0) {
@ -58,12 +58,12 @@ public class EdStraightPoleBlock extends StandardBlocks.DirectedWaterLoggable
@Override
@SuppressWarnings("deprecation")
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit)
{
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
if ((hit.getDirection().getAxis() == state.getValue(FACING).getAxis())) return InteractionResult.PASS;
final ItemStack held_stack = player.getItemInHand(hand);
if ((held_stack.isEmpty()) || (!(held_stack.getItem() instanceof BlockItem))) return InteractionResult.PASS;
if(!(((BlockItem)(held_stack.getItem())).getBlock() instanceof EdStraightPoleBlock)) return InteractionResult.PASS;
if (!(((BlockItem) (held_stack.getItem())).getBlock() instanceof EdStraightPoleBlock))
return InteractionResult.PASS;
if (held_stack.getItem() != default_pole.asItem()) return InteractionResult.sidedSuccess(world.isClientSide());
final Block held_block = ((BlockItem) (held_stack.getItem())).getBlock();
final Direction block_direction = state.getValue(FACING);

View file

@ -8,7 +8,8 @@
*/
package dev.zontreck.engineerdecor.blocks;
import dev.zontreck.engineerdecor.libmc.*;
import dev.zontreck.engineerdecor.ModContent;
import dev.zontreck.libzontreck.edlibmc.*;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
@ -20,7 +21,7 @@ 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.LevelReader;
import net.minecraft.world.level.SignalGetter;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockBehaviour;
@ -38,9 +39,6 @@ import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.registries.ForgeRegistries;
import dev.zontreck.engineerdecor.ModContent;
import wile.engineersdecor.libmc.*;
import javax.annotation.Nullable;
import java.util.ArrayList;
@ -48,46 +46,51 @@ import java.util.Collections;
import java.util.List;
public class EdTestBlock
{
public class EdTestBlock {
//--------------------------------------------------------------------------------------------------------------------
// Block
//--------------------------------------------------------------------------------------------------------------------
public static class TestBlock extends StandardBlocks.Directed implements StandardEntityBlocks.IStandardEntityBlock<TestTileEntity>, Auxiliaries.IExperimentalFeature
{
public TestBlock(long config, BlockBehaviour.Properties builder, final AABB unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
public static class TestBlock extends StandardBlocks.Directed implements StandardEntityBlocks.IStandardEntityBlock<TestTileEntity>, Auxiliaries.IExperimentalFeature {
public TestBlock(long config, BlockBehaviour.Properties builder, final AABB unrotatedAABB) {
super(config, builder, unrotatedAABB);
}
@Override
public boolean isBlockEntityTicking(Level world, BlockState state)
{ return true; }
public boolean isBlockEntityTicking(Level world, BlockState state) {
return true;
}
@Override
public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext)
{ return Shapes.block(); }
@Override
@SuppressWarnings("deprecation") // public boolean canConnectRedstone(BlockState state, BlockGetter world, BlockPos pos, @Nullable Direction side) { return true; }
public boolean isSignalSource(BlockState p_60571_)
{ return true; }
@Override
public boolean shouldCheckWeakPower(BlockState state, LevelReader world, BlockPos pos, Direction side)
{ return false; }
@Override
public boolean hasDynamicDropList()
{ return true; }
@Override
public List<ItemStack> dropList(BlockState state, Level world, BlockEntity te, boolean explosion)
{ return Collections.singletonList(new ItemStack(this)); }
public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) {
return Shapes.block();
}
@Override
@SuppressWarnings("deprecation")
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit)
{
// public boolean canConnectRedstone(BlockState state, BlockGetter world, BlockPos pos, @Nullable Direction side) { return true; }
public boolean isSignalSource(BlockState p_60571_) {
return true;
}
@Override
public boolean shouldCheckWeakPower(BlockState state, SignalGetter level, BlockPos pos, Direction side) {
return false;
}
@Override
public boolean hasDynamicDropList() {
return true;
}
@Override
public List<ItemStack> dropList(BlockState state, Level world, BlockEntity te, boolean explosion) {
return Collections.singletonList(new ItemStack(this));
}
@Override
@SuppressWarnings("deprecation")
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
if (world.isClientSide()) return InteractionResult.SUCCESS;
BlockEntity te = world.getBlockEntity(pos);
if (!(te instanceof TestTileEntity)) return InteractionResult.FAIL;
@ -99,8 +102,7 @@ public class EdTestBlock
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
public static class TestTileEntity extends StandardEntityBlocks.StandardBlockEntity
{
public static class TestTileEntity extends StandardEntityBlocks.StandardBlockEntity {
private final RfEnergy.Battery battery_;
private final LazyOptional<IEnergyStorage> energy_handler_;
private final Fluidics.Tank tank_;
@ -127,8 +129,7 @@ public class EdTestBlock
private boolean paused = false;
public TestTileEntity(BlockPos pos, BlockState state)
{
public TestTileEntity(BlockPos pos, BlockState state) {
super(ModContent.getBlockEntityTypeOfBlock(state.getBlock()), pos, state);
battery_ = new RfEnergy.Battery((int) 1e9, (int) 1e9, 0, 0);
energy_handler_ = battery_.createEnergyHandler();
@ -139,8 +140,7 @@ public class EdTestBlock
}
@Override
public void load(CompoundTag nbt)
{
public void load(CompoundTag nbt) {
super.load(nbt);
tank_.load(nbt);
battery_.load(nbt);
@ -157,13 +157,13 @@ public class EdTestBlock
rf_feed_setting = nbt.getInt("rf_feed_setting");
items_received_total = nbt.getInt("items_received_total");
items_inserted_total = nbt.getInt("items_inserted_total");
if(nbt.contains("liq_fill_stack")) liq_fill_stack = FluidStack.loadFluidStackFromNBT(nbt.getCompound("liq_fill_stack"));
if (nbt.contains("liq_fill_stack"))
liq_fill_stack = FluidStack.loadFluidStackFromNBT(nbt.getCompound("liq_fill_stack"));
if (nbt.contains("insertion_item")) insertion_item = ItemStack.of(nbt.getCompound("insertion_item"));
}
@Override
protected void saveAdditional(CompoundTag nbt)
{
protected void saveAdditional(CompoundTag nbt) {
super.saveAdditional(nbt);
tank_.save(nbt);
battery_.save(nbt);
@ -184,24 +184,21 @@ public class EdTestBlock
if (!insertion_item.isEmpty()) nbt.put("insertion_item", insertion_item.save(new CompoundTag()));
}
private FluidStack getFillFluid(ItemStack stack)
{
private FluidStack getFillFluid(ItemStack stack) {
// intentionally not item fluid handler, only specific items.
if (stack.getItem() == Items.WATER_BUCKET) return new FluidStack(Fluids.WATER, 1000);
if (stack.getItem() == Items.LAVA_BUCKET) return new FluidStack(Fluids.LAVA, 1000);
return FluidStack.EMPTY;
}
private ItemStack getRandomItemstack()
{
private ItemStack getRandomItemstack() {
final int n = (int) Math.floor(Math.random() * ForgeRegistries.ITEMS.getValues().size());
ItemStack stack = new ItemStack(ForgeRegistries.ITEMS.getValues().stream().skip(n).findAny().orElse(Items.COBBLESTONE));
stack.setCount((int) Math.floor(Math.random() * stack.getMaxStackSize()));
return stack;
}
public boolean activated(Player player, InteractionHand hand, BlockHitResult hit)
{
public boolean activated(Player player, InteractionHand hand, BlockHitResult hit) {
final ItemStack held = player.getItemInHand(hand);
if (held.isEmpty()) {
ArrayList<String> msgs = new ArrayList<>();
@ -252,8 +249,7 @@ public class EdTestBlock
}
@Override
public void setRemoved()
{
public void setRemoved() {
super.setRemoved();
energy_handler_.invalidate();
fluid_handler_.invalidate();
@ -261,8 +257,7 @@ public class EdTestBlock
}
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing) {
if ((!paused) && (facing != block_facing)) {
if (capability == ForgeCapabilities.FLUID_HANDLER) return fluid_handler_.cast();
if (capability == ForgeCapabilities.ENERGY) return energy_handler_.cast();
@ -272,8 +267,7 @@ public class EdTestBlock
}
@Override
public void tick()
{
public void tick() {
if (level.isClientSide()) return;
block_facing = getBlockState().getValue(TestBlock.FACING);
paused = level.hasNeighborSignal(getBlockPos());

View file

@ -8,7 +8,13 @@
*/
package dev.zontreck.engineerdecor.blocks;
import dev.zontreck.engineerdecor.ModConfig;
import dev.zontreck.engineerdecor.ModContent;
import dev.zontreck.engineerdecor.detail.TreeCutting;
import dev.zontreck.libzontreck.edlibmc.Auxiliaries;
import dev.zontreck.libzontreck.edlibmc.Overlay;
import dev.zontreck.libzontreck.edlibmc.StandardBlocks;
import dev.zontreck.libzontreck.edlibmc.StandardEntityBlocks;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.particles.ParticleTypes;
@ -21,7 +27,7 @@ import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.SignalGetter;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockBehaviour;
@ -35,53 +41,50 @@ import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.capabilities.ForgeCapabilities;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.energy.IEnergyStorage;
import dev.zontreck.engineerdecor.ModConfig;
import dev.zontreck.engineerdecor.ModContent;
import dev.zontreck.engineerdecor.libmc.StandardBlocks;
import dev.zontreck.engineerdecor.libmc.StandardEntityBlocks;
import dev.zontreck.engineerdecor.libmc.Auxiliaries;
import dev.zontreck.engineerdecor.libmc.Overlay;
import javax.annotation.Nullable;
import java.util.Random;
public class EdTreeCutter
{
public static void on_config(int boost_energy_per_tick, int cutting_time_seconds, boolean power_required)
{ TreeCutterTileEntity.on_config(boost_energy_per_tick, cutting_time_seconds,power_required); }
public class EdTreeCutter {
public static void on_config(int boost_energy_per_tick, int cutting_time_seconds, boolean power_required) {
TreeCutterTileEntity.on_config(boost_energy_per_tick, cutting_time_seconds, power_required);
}
//--------------------------------------------------------------------------------------------------------------------
// Block
//--------------------------------------------------------------------------------------------------------------------
public static class TreeCutterBlock extends StandardBlocks.Horizontal implements StandardEntityBlocks.IStandardEntityBlock<TreeCutterTileEntity>
{
public static class TreeCutterBlock extends StandardBlocks.Horizontal implements StandardEntityBlocks.IStandardEntityBlock<TreeCutterTileEntity> {
public static final BooleanProperty ACTIVE = BooleanProperty.create("active");
public TreeCutterBlock(long config, BlockBehaviour.Properties builder, final AABB[] unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
public TreeCutterBlock(long config, BlockBehaviour.Properties builder, final AABB[] unrotatedAABB) {
super(config, builder, unrotatedAABB);
}
@Override
public boolean isBlockEntityTicking(Level world, BlockState state)
{ return true; }
public boolean isBlockEntityTicking(Level world, BlockState state) {
return true;
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder)
{ super.createBlockStateDefinition(builder); builder.add(ACTIVE); }
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
super.createBlockStateDefinition(builder);
builder.add(ACTIVE);
}
@Override
@Nullable
public BlockState getStateForPlacement(BlockPlaceContext context)
{ return super.getStateForPlacement(context).setValue(ACTIVE, false); }
public BlockState getStateForPlacement(BlockPlaceContext context) {
return super.getStateForPlacement(context).setValue(ACTIVE, false);
}
@OnlyIn(Dist.CLIENT)
public void animateTick(BlockState state, Level world, BlockPos pos, Random rnd)
{
public void animateTick(BlockState state, Level world, BlockPos pos, Random rnd) {
if ((state.getBlock() != this) || (!state.getValue(ACTIVE))) return;
// Sound
/*if((world.getGameTime() & 0x1) == 0)*/ {
/*if((world.getGameTime() & 0x1) == 0)*/
{
world.playLocalSound(pos.getX(), pos.getY(), pos.getZ(), SoundEvents.WOOD_HIT, SoundSource.BLOCKS, 0.1f, 1.0f, false);
}
// Particles
@ -102,8 +105,7 @@ public class EdTreeCutter
@Override
@SuppressWarnings("deprecation")
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit)
{
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
if (world.isClientSide()) return InteractionResult.SUCCESS;
BlockEntity te = world.getBlockEntity(pos);
if (te instanceof TreeCutterTileEntity) ((TreeCutterTileEntity) te).state_message(player);
@ -111,16 +113,16 @@ public class EdTreeCutter
}
@Override
public boolean shouldCheckWeakPower(BlockState state, LevelReader world, BlockPos pos, Direction side)
{ return false; }
public boolean shouldCheckWeakPower(BlockState state, SignalGetter level, BlockPos pos, Direction side) {
return false;
}
}
//--------------------------------------------------------------------------------------------------------------------
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
public static class TreeCutterTileEntity extends StandardEntityBlocks.StandardBlockEntity implements IEnergyStorage
{
public static class TreeCutterTileEntity extends StandardEntityBlocks.StandardBlockEntity implements IEnergyStorage {
public static final int IDLE_TICK_INTERVAL = 40;
public static final int TICK_INTERVAL = 5;
public static final int BOOST_FACTOR = 6;
@ -130,14 +132,17 @@ public class EdTreeCutter
private static int energy_max = DEFAULT_BOOST_ENERGY * 20;
private static int cutting_time_needed = 20 * DEFAULT_CUTTING_TIME_NEEDED;
private static boolean requires_power = false;
protected LazyOptional<IEnergyStorage> energy_handler_ = LazyOptional.of(() -> this);
private int tick_timer_;
private int active_timer_;
private int proc_time_elapsed_;
private int energy_;
public static void on_config(int boost_energy_per_tick, int cutting_time_seconds, boolean power_required)
{
public TreeCutterTileEntity(BlockPos pos, BlockState state) {
super(ModContent.getBlockEntityTypeOfBlock(state.getBlock()), pos, state);
}
public static void on_config(int boost_energy_per_tick, int cutting_time_seconds, boolean power_required) {
boost_energy_consumption = TICK_INTERVAL * Mth.clamp(boost_energy_per_tick, 4, 4096);
energy_max = Math.max(boost_energy_consumption * 10, 10000);
cutting_time_needed = 20 * Mth.clamp(cutting_time_seconds, 10, 240);
@ -145,17 +150,17 @@ public class EdTreeCutter
ModConfig.log("Config tree cutter: energy consumption:" + (boost_energy_consumption / TICK_INTERVAL) + "rf/t" + (requires_power ? " (power required for operation) " : "") + ", cutting time:" + cutting_time_needed + "t.");
}
public TreeCutterTileEntity(BlockPos pos, BlockState state)
{ super(ModContent.getBlockEntityTypeOfBlock(state.getBlock()), pos, state); }
public void readnbt(CompoundTag nbt) {
energy_ = nbt.getInt("energy");
}
public void readnbt(CompoundTag nbt)
{ energy_ = nbt.getInt("energy"); }
private void writenbt(CompoundTag nbt) {
nbt.putInt("energy", energy_);
}
private void writenbt(CompoundTag nbt)
{ nbt.putInt("energy", energy_); }
// BlockEntity ------------------------------------------------------------------------------
public void state_message(Player player)
{
public void state_message(Player player) {
String progress = "0";
if ((active_timer_ > 0) && (cutting_time_needed > 0) && (active_timer_ > 0)) {
progress = Integer.toString((int) Mth.clamp((((double) proc_time_elapsed_) / ((double) cutting_time_needed) * 100), 0, 100));
@ -164,50 +169,53 @@ public class EdTreeCutter
Overlay.show(player, Auxiliaries.localizable("block.engineersdecor.small_tree_cutter.status", soc, energy_max, progress, (cutting_time_needed / 20)));
}
// BlockEntity ------------------------------------------------------------------------------
@Override
public void load(CompoundTag nbt) {
super.load(nbt);
readnbt(nbt);
}
@Override
public void load(CompoundTag nbt)
{ super.load(nbt); readnbt(nbt); }
@Override
protected void saveAdditional(CompoundTag nbt)
{ super.saveAdditional(nbt); writenbt(nbt); }
@Override
public void setRemoved()
{
super.setRemoved();
energy_handler_.invalidate();
protected void saveAdditional(CompoundTag nbt) {
super.saveAdditional(nbt);
writenbt(nbt);
}
// IEnergyStorage ----------------------------------------------------------------------------
protected LazyOptional<IEnergyStorage> energy_handler_ = LazyOptional.of(() -> this);
@Override
public void setRemoved() {
super.setRemoved();
energy_handler_.invalidate();
}
@Override
public boolean canExtract()
{ return false; }
public boolean canExtract() {
return false;
}
@Override
public boolean canReceive()
{ return true; }
public boolean canReceive() {
return true;
}
@Override
public int getMaxEnergyStored()
{ return boost_energy_consumption*2; }
public int getMaxEnergyStored() {
return boost_energy_consumption * 2;
}
@Override
public int getEnergyStored()
{ return energy_; }
public int getEnergyStored() {
return energy_;
}
@Override
public int extractEnergy(int maxExtract, boolean simulate)
{ return 0; }
public int extractEnergy(int maxExtract, boolean simulate) {
return 0;
}
@Override
public int receiveEnergy(int maxReceive, boolean simulate)
{
public int receiveEnergy(int maxReceive, boolean simulate) {
maxReceive = Mth.clamp(maxReceive, 0, Math.max((energy_max) - energy_, 0));
if (!simulate) energy_ += maxReceive;
return maxReceive;
@ -216,8 +224,7 @@ public class EdTreeCutter
// Capability export ----------------------------------------------------------------------------
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing) {
if (capability == ForgeCapabilities.ENERGY) return energy_handler_.cast();
return super.getCapability(capability, facing);
}
@ -225,8 +232,7 @@ public class EdTreeCutter
// ITickable ------------------------------------------------------------------------------------
@Override
public void tick()
{
public void tick() {
if (--tick_timer_ > 0) return;
tick_timer_ = TICK_INTERVAL;
final BlockState device_state = level.getBlockState(worldPosition);
@ -234,7 +240,8 @@ public class EdTreeCutter
final BlockPos tree_pos = worldPosition.relative(device_state.getValue(TreeCutterBlock.HORIZONTAL_FACING));
final BlockState tree_state = level.getBlockState(tree_pos);
if (!TreeCutting.canChop(level, tree_state, tree_pos) || (level.hasNeighborSignal(worldPosition))) {
if(device_state.getValue(TreeCutterBlock.ACTIVE)) level.setBlock(worldPosition, device_state.setValue(TreeCutterBlock.ACTIVE, false), 1|2);
if (device_state.getValue(TreeCutterBlock.ACTIVE))
level.setBlock(worldPosition, device_state.setValue(TreeCutterBlock.ACTIVE, false), 1 | 2);
proc_time_elapsed_ = 0;
active_timer_ = 0;
tick_timer_ = IDLE_TICK_INTERVAL;

View file

@ -8,6 +8,7 @@
*/
package dev.zontreck.engineerdecor.blocks;
import dev.zontreck.libzontreck.edlibmc.VariantWallBlock;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.LevelReader;
@ -15,16 +16,14 @@ import net.minecraft.world.level.block.IronBarsBlock;
import net.minecraft.world.level.block.StainedGlassPaneBlock;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState;
import dev.zontreck.engineerdecor.libmc.VariantWallBlock;
public class EdWallBlock extends VariantWallBlock
{
public EdWallBlock(long config, BlockBehaviour.Properties builder)
{ super(config, builder); }
public class EdWallBlock extends VariantWallBlock {
public EdWallBlock(long config, BlockBehaviour.Properties builder) {
super(config, builder);
}
protected boolean attachesTo(BlockState facingState, LevelReader world, BlockPos facingPos, Direction side)
{
protected boolean attachesTo(BlockState facingState, LevelReader world, BlockPos facingPos, Direction side) {
if (facingState == null) return false;
if (super.attachesTo(facingState, world, facingPos, side)) return true;
if (facingState.getBlock() instanceof EdWindowBlock) return true;

View file

@ -8,7 +8,9 @@
*/
package dev.zontreck.engineerdecor.blocks;
import dev.zontreck.engineerdecor.libmc.RfEnergy;
import dev.zontreck.engineerdecor.ModConfig;
import dev.zontreck.engineerdecor.ModContent;
import dev.zontreck.libzontreck.edlibmc.*;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.particles.ParticleTypes;
@ -26,7 +28,7 @@ import net.minecraft.world.inventory.*;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.SignalGetter;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockBehaviour;
@ -41,29 +43,19 @@ import net.minecraftforge.common.capabilities.ForgeCapabilities;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.energy.IEnergyStorage;
import net.minecraftforge.items.IItemHandler;
import dev.zontreck.engineerdecor.ModConfig;
import dev.zontreck.engineerdecor.ModContent;
import dev.zontreck.engineerdecor.libmc.StandardBlocks;
import dev.zontreck.engineerdecor.libmc.StandardEntityBlocks;
import dev.zontreck.engineerdecor.libmc.Auxiliaries;
import dev.zontreck.engineerdecor.libmc.Inventories;
import dev.zontreck.engineerdecor.libmc.RsSignals;
import dev.zontreck.engineerdecor.libmc.Guis;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
public class EdWasteIncinerator
{
public class EdWasteIncinerator {
public static final int MAX_ENERGY_BUFFER = 16000;
public static final int MAX_ENERGY_TRANSFER = 256;
public static final int DEFAULT_ENERGY_CONSUMPTION = 16;
private static int energy_consumption = DEFAULT_ENERGY_CONSUMPTION;
public static void on_config(int boost_energy_per_tick)
{
public static void on_config(int boost_energy_per_tick) {
energy_consumption = Mth.clamp(boost_energy_per_tick, 4, 4096);
ModConfig.log("Config waste incinerator: boost energy consumption:" + energy_consumption + ".");
}
@ -72,43 +64,49 @@ public class EdWasteIncinerator
// Block
//--------------------------------------------------------------------------------------------------------------------
public static class WasteIncineratorBlock extends StandardBlocks.Cutout implements StandardEntityBlocks.IStandardEntityBlock<WasteIncineratorTileEntity>
{
public static class WasteIncineratorBlock extends StandardBlocks.Cutout implements StandardEntityBlocks.IStandardEntityBlock<WasteIncineratorTileEntity> {
public static final BooleanProperty LIT = EdFurnace.FurnaceBlock.LIT;
public WasteIncineratorBlock(long config, BlockBehaviour.Properties builder, final AABB unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
public WasteIncineratorBlock(long config, BlockBehaviour.Properties builder, final AABB unrotatedAABB) {
super(config, builder, unrotatedAABB);
}
@Override
public boolean isBlockEntityTicking(Level world, BlockState state)
{ return true; }
public boolean isBlockEntityTicking(Level world, BlockState state) {
return true;
}
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder)
{ super.createBlockStateDefinition(builder); builder.add(LIT); }
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
super.createBlockStateDefinition(builder);
builder.add(LIT);
}
@Override
@Nullable
public BlockState getStateForPlacement(BlockPlaceContext context)
{ return super.getStateForPlacement(context).setValue(LIT, false); }
public BlockState getStateForPlacement(BlockPlaceContext context) {
return super.getStateForPlacement(context).setValue(LIT, false);
}
@Override
@SuppressWarnings("deprecation")
public boolean hasAnalogOutputSignal(BlockState state)
{ return true; }
public boolean hasAnalogOutputSignal(BlockState state) {
return true;
}
@Override
@SuppressWarnings("deprecation")
public int getAnalogOutputSignal(BlockState blockState, Level world, BlockPos pos)
{ return (!(world.getBlockEntity(pos) instanceof WasteIncineratorTileEntity te)) ? 0 : RsSignals.fromContainer(te.main_inventory_); }
public int getAnalogOutputSignal(BlockState blockState, Level world, BlockPos pos) {
return (!(world.getBlockEntity(pos) instanceof WasteIncineratorTileEntity te)) ? 0 : RsSignals.fromContainer(te.main_inventory_);
}
@Override
public boolean shouldCheckWeakPower(BlockState state, LevelReader world, BlockPos pos, Direction side)
{ return false; }
public boolean shouldCheckWeakPower(BlockState state, SignalGetter level, BlockPos pos, Direction side) {
return false;
}
@Override
public void setPlacedBy(Level world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack)
{
public void setPlacedBy(Level world, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) {
if (world.isClientSide) return;
if ((!stack.hasTag()) || (!stack.getTag().contains("tedata"))) return;
CompoundTag te_nbt = stack.getTag().getCompound("tedata");
@ -120,12 +118,12 @@ public class EdWasteIncinerator
}
@Override
public boolean hasDynamicDropList()
{ return true; }
public boolean hasDynamicDropList() {
return true;
}
@Override
public List<ItemStack> dropList(BlockState state, Level world, final BlockEntity te, boolean explosion)
{
public List<ItemStack> dropList(BlockState state, Level world, final BlockEntity te, boolean explosion) {
final List<ItemStack> stacks = new ArrayList<>();
if (world.isClientSide) return stacks;
if (!(te instanceof WasteIncineratorTileEntity)) return stacks;
@ -147,13 +145,13 @@ public class EdWasteIncinerator
@Override
@SuppressWarnings("deprecation")
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult rayTraceResult)
{ return useOpenGui(state, world, pos, player); }
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult rayTraceResult) {
return useOpenGui(state, world, pos, player);
}
@Override
@OnlyIn(Dist.CLIENT)
public void animateTick(BlockState state, Level world, BlockPos pos, RandomSource rnd)
{
public void animateTick(BlockState state, Level world, BlockPos pos, RandomSource rnd) {
if ((state.getBlock() != this) || (!state.getValue(LIT))) return;
final double rv = rnd.nextDouble();
if (rv > 0.5) return;
@ -167,8 +165,7 @@ public class EdWasteIncinerator
// Tile entity
//--------------------------------------------------------------------------------------------------------------------
public static class WasteIncineratorTileEntity extends StandardEntityBlocks.StandardBlockEntity implements MenuProvider, Nameable
{
public static class WasteIncineratorTileEntity extends StandardEntityBlocks.StandardBlockEntity implements MenuProvider, Nameable {
public static final int NUM_OF_FIELDS = 1;
public static final int TICK_INTERVAL = 20;
public static final int ENERGIZED_TICK_INTERVAL = 5;
@ -178,107 +175,112 @@ public class EdWasteIncinerator
public static final int BURN_SLOT_NO = NUM_OF_SLOTS - 1;
// WasteIncineratorTileEntity -----------------------------------------------------------------------------
protected final ContainerData fields = new ContainerData() {
@Override
public int getCount() {
return WasteIncineratorTileEntity.NUM_OF_FIELDS;
}
private int tick_timer_;
private int check_timer_;
@Override
public int get(int id) {
return switch (id) {
default -> 0;
};
}
@Override
public void set(int id, int value) {
}
};
private final Inventories.StorageInventory main_inventory_ = new Inventories.StorageInventory(this, NUM_OF_SLOTS, 1);
private final LazyOptional<? extends IItemHandler> item_handler_ = Inventories.MappedItemHandler.createInsertionHandler(main_inventory_, INPUT_SLOT_NO);
private final RfEnergy.Battery battery_ = new RfEnergy.Battery(MAX_ENERGY_BUFFER, MAX_ENERGY_TRANSFER, 0);
private final LazyOptional<IEnergyStorage> energy_handler_ = battery_.createEnergyHandler();
private int tick_timer_;
private int check_timer_;
public WasteIncineratorTileEntity(BlockPos pos, BlockState state)
{ super(ModContent.getBlockEntityTypeOfBlock(state.getBlock()), pos, state); reset(); }
public WasteIncineratorTileEntity(BlockPos pos, BlockState state) {
super(ModContent.getBlockEntityTypeOfBlock(state.getBlock()), pos, state);
reset();
}
public CompoundTag getnbt()
{ return writenbt(new CompoundTag()); }
public CompoundTag getnbt() {
return writenbt(new CompoundTag());
}
protected void reset()
{
protected void reset() {
main_inventory_.clearContent();
check_timer_ = 0;
tick_timer_ = 0;
}
public void readnbt(CompoundTag nbt)
{
public void readnbt(CompoundTag nbt) {
main_inventory_.load(nbt);
battery_.load(nbt);
}
protected CompoundTag writenbt(CompoundTag nbt)
{
// BlockEntity ------------------------------------------------------------------------------
protected CompoundTag writenbt(CompoundTag nbt) {
main_inventory_.save(nbt);
battery_.save(nbt);
return nbt;
}
// BlockEntity ------------------------------------------------------------------------------
@Override
public void load(CompoundTag nbt) {
super.load(nbt);
readnbt(nbt);
}
@Override
public void load(CompoundTag nbt)
{ super.load(nbt); readnbt(nbt); }
@Override
protected void saveAdditional(CompoundTag nbt)
{ super.saveAdditional(nbt); writenbt(nbt); }
@Override
public void setRemoved()
{
super.setRemoved();
energy_handler_.invalidate();
item_handler_.invalidate();
protected void saveAdditional(CompoundTag nbt) {
super.saveAdditional(nbt);
writenbt(nbt);
}
// INameable ---------------------------------------------------------------------------
@Override
public Component getName()
{ return Auxiliaries.localizable(getBlockState().getBlock().getDescriptionId()); }
public void setRemoved() {
super.setRemoved();
energy_handler_.invalidate();
item_handler_.invalidate();
}
@Override
public boolean hasCustomName()
{ return false; }
public Component getName() {
return Auxiliaries.localizable(getBlockState().getBlock().getDescriptionId());
}
@Override
public Component getCustomName()
{ return getName(); }
public boolean hasCustomName() {
return false;
}
// IContainerProvider ----------------------------------------------------------------------
@Override
public Component getDisplayName()
{ return Nameable.super.getDisplayName(); }
public Component getCustomName() {
return getName();
}
@Override
public AbstractContainerMenu createMenu(int id, Inventory inventory, Player player )
{ return new EdWasteIncinerator.WasteIncineratorContainer(id, inventory, main_inventory_, ContainerLevelAccess.create(level, worldPosition), fields); }
public Component getDisplayName() {
return Nameable.super.getDisplayName();
}
// Fields -----------------------------------------------------------------------------------------------
protected final ContainerData fields = new ContainerData()
{
@Override
public int getCount()
{ return WasteIncineratorTileEntity.NUM_OF_FIELDS; }
@Override
public int get(int id)
{
return switch (id) {
default -> 0;
};
public AbstractContainerMenu createMenu(int id, Inventory inventory, Player player) {
return new EdWasteIncinerator.WasteIncineratorContainer(id, inventory, main_inventory_, ContainerLevelAccess.create(level, worldPosition), fields);
}
@Override
public void set(int id, int value)
{}
};
// Capability export ----------------------------------------------------------------------------
@Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing)
{
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing) {
if (capability == ForgeCapabilities.ITEM_HANDLER) return item_handler_.cast();
if (capability == ForgeCapabilities.ENERGY) return energy_handler_.cast();
return super.getCapability(capability, facing);
@ -287,8 +289,7 @@ public class EdWasteIncinerator
// -----------------------------------------------------------------------------------------------------------------
@Override
public void tick()
{
public void tick() {
if (--tick_timer_ > 0) return;
tick_timer_ = TICK_INTERVAL;
if (level.isClientSide) return;
@ -297,7 +298,8 @@ public class EdWasteIncinerator
final boolean was_processing = !processing_stack.isEmpty();
boolean is_processing = was_processing;
boolean new_stack_processing = false;
if((!main_inventory_.getItem(0).isEmpty()) && transferItems(0, 1, main_inventory_.getMaxStackSize())) dirty = true;
if ((!main_inventory_.getItem(0).isEmpty()) && transferItems(0, 1, main_inventory_.getMaxStackSize()))
dirty = true;
ItemStack first_stack = main_inventory_.getItem(0);
boolean shift = !first_stack.isEmpty();
if (is_processing) {
@ -323,7 +325,8 @@ public class EdWasteIncinerator
}
}
if ((was_processing != is_processing) || (new_stack_processing)) {
if(new_stack_processing) level.playSound(null, worldPosition, SoundEvents.LAVA_AMBIENT, SoundSource.BLOCKS, 0.05f, 2.4f);
if (new_stack_processing)
level.playSound(null, worldPosition, SoundEvents.LAVA_AMBIENT, SoundSource.BLOCKS, 0.05f, 2.4f);
final BlockState state = level.getBlockState(worldPosition);
if (state.getBlock() instanceof WasteIncineratorBlock) {
level.setBlock(worldPosition, state.setValue(WasteIncineratorBlock.LIT, is_processing), 2 | 16);
@ -334,8 +337,7 @@ public class EdWasteIncinerator
// Aux methods ----------------------------------------------------------------------------------
private ItemStack shiftStacks(final int index_from, final int index_to)
{
private ItemStack shiftStacks(final int index_from, final int index_to) {
if (index_from >= index_to) return ItemStack.EMPTY;
ItemStack out_stack = ItemStack.EMPTY;
ItemStack stack = main_inventory_.getItem(index_from);
@ -348,8 +350,7 @@ public class EdWasteIncinerator
return out_stack;
}
private boolean transferItems(final int index_from, final int index_to, int count)
{
private boolean transferItems(final int index_from, final int index_to, int count) {
ItemStack from = main_inventory_.getItem(index_from);
if (from.isEmpty()) return false;
ItemStack to = main_inventory_.getItem(index_to);
@ -383,8 +384,7 @@ public class EdWasteIncinerator
// Container
//--------------------------------------------------------------------------------------------------------------------
public static class WasteIncineratorContainer extends AbstractContainerMenu
{
public static class WasteIncineratorContainer extends AbstractContainerMenu {
private static final int PLAYER_INV_START_SLOTNO = WasteIncineratorTileEntity.NUM_OF_SLOTS;
protected final Player player_;
protected final Container inventory_;
@ -392,16 +392,11 @@ public class EdWasteIncinerator
private final ContainerData fields_;
private int proc_time_needed_;
public int field(int index) { return fields_.get(index); }
public Player player() { return player_ ; }
public Container inventory() { return inventory_ ; }
public Level world() { return player_.level; }
public WasteIncineratorContainer(int cid, Inventory player_inventory) {
this(cid, player_inventory, new SimpleContainer(WasteIncineratorTileEntity.NUM_OF_SLOTS), ContainerLevelAccess.NULL, new SimpleContainerData(WasteIncineratorTileEntity.NUM_OF_FIELDS));
}
public WasteIncineratorContainer(int cid, Inventory player_inventory)
{ this(cid, player_inventory, new SimpleContainer(WasteIncineratorTileEntity.NUM_OF_SLOTS), ContainerLevelAccess.NULL, new SimpleContainerData(WasteIncineratorTileEntity.NUM_OF_FIELDS)); }
private WasteIncineratorContainer(int cid, Inventory player_inventory, Container block_inventory, ContainerLevelAccess wpc, ContainerData fields)
{
private WasteIncineratorContainer(int cid, Inventory player_inventory, Container block_inventory, ContainerLevelAccess wpc, ContainerData fields) {
super(ModContent.getMenuType("small_waste_incinerator"), cid); // @todo: class mapping
player_ = player_inventory.player;
inventory_ = block_inventory;
@ -434,20 +429,37 @@ public class EdWasteIncinerator
}
}
@Override
public boolean stillValid(Player player)
{ return inventory_.stillValid(player); }
public int field(int index) {
return fields_.get(index);
}
public Player player() {
return player_;
}
public Container inventory() {
return inventory_;
}
public Level world() {
return player_.level();
}
@Override
public ItemStack quickMoveStack(Player player, int index)
{
public boolean stillValid(Player player) {
return inventory_.stillValid(player);
}
@Override
public ItemStack quickMoveStack(Player player, int index) {
Slot slot = getSlot(index);
if ((slot == null) || (!slot.hasItem())) return ItemStack.EMPTY;
ItemStack slot_stack = slot.getItem();
ItemStack transferred = slot_stack.copy();
if ((index >= 0) && (index < PLAYER_INV_START_SLOTNO)) {
// Device slots
if(!moveItemStackTo(slot_stack, PLAYER_INV_START_SLOTNO, PLAYER_INV_START_SLOTNO+36, true)) return ItemStack.EMPTY;
if (!moveItemStackTo(slot_stack, PLAYER_INV_START_SLOTNO, PLAYER_INV_START_SLOTNO + 36, true))
return ItemStack.EMPTY;
} else if ((index >= PLAYER_INV_START_SLOTNO) && (index <= PLAYER_INV_START_SLOTNO + 36)) {
// Player slot
if (!moveItemStackTo(slot_stack, 0, PLAYER_INV_START_SLOTNO - 1, true)) return ItemStack.EMPTY;
@ -471,10 +483,10 @@ public class EdWasteIncinerator
//--------------------------------------------------------------------------------------------------------------------
@OnlyIn(Dist.CLIENT)
public static class WasteIncineratorGui extends Guis.ContainerGui<WasteIncineratorContainer>
{
public WasteIncineratorGui(WasteIncineratorContainer container, Inventory player_inventory, Component title)
{ super(container, player_inventory, title, "textures/gui/small_waste_incinerator_gui.png"); }
public static class WasteIncineratorGui extends Guis.ContainerGui<WasteIncineratorContainer> {
public WasteIncineratorGui(WasteIncineratorContainer container, Inventory player_inventory, Component title) {
super(container, player_inventory, title, "textures/gui/small_waste_incinerator_gui.png");
}
}
}

View file

@ -8,6 +8,7 @@
*/
package dev.zontreck.engineerdecor.blocks;
import dev.zontreck.libzontreck.edlibmc.StandardBlocks;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.sounds.SoundEvents;
@ -24,26 +25,24 @@ import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Fluids;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.BlockHitResult;
import dev.zontreck.engineerdecor.libmc.StandardBlocks;
import javax.annotation.Nullable;
import java.util.Arrays;
public class EdWindowBlock extends StandardBlocks.DirectedWaterLoggable
{
public EdWindowBlock(long config, BlockBehaviour.Properties builder, final AABB unrotatedAABB)
{ super(config, builder, unrotatedAABB); }
public class EdWindowBlock extends StandardBlocks.DirectedWaterLoggable {
public EdWindowBlock(long config, BlockBehaviour.Properties builder, final AABB unrotatedAABB) {
super(config, builder, unrotatedAABB);
}
@Override
public RenderTypeHint getRenderTypeHint()
{ return RenderTypeHint.TRANSLUCENT; }
public RenderTypeHint getRenderTypeHint() {
return RenderTypeHint.TRANSLUCENT;
}
@Override
@Nullable
public BlockState getStateForPlacement(BlockPlaceContext context)
{
public BlockState getStateForPlacement(BlockPlaceContext context) {
Direction facing = context.getHorizontalDirection();
if (Math.abs(context.getPlayer().getLookAngle().y) > 0.9) {
facing = context.getNearestLookingDirection();
@ -61,8 +60,7 @@ public class EdWindowBlock extends StandardBlocks.DirectedWaterLoggable
@Override
@SuppressWarnings("deprecation")
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit)
{
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
if (player.getItemInHand(hand).getItem() != asItem()) return InteractionResult.PASS;
final Direction facing = state.getValue(FACING);
if (facing.getAxis() != hit.getDirection().getAxis()) return InteractionResult.PASS;
@ -82,12 +80,14 @@ public class EdWindowBlock extends StandardBlocks.DirectedWaterLoggable
}
@Override
public boolean propagatesSkylightDown(BlockState state, BlockGetter reader, BlockPos pos)
{ return true; }
public boolean propagatesSkylightDown(BlockState state, BlockGetter reader, BlockPos pos) {
return true;
}
@Override
@SuppressWarnings("deprecation")
public boolean useShapeForLightOcclusion(BlockState state)
{ return true; }
public boolean useShapeForLightOcclusion(BlockState state) {
return true;
}
}

View file

@ -8,6 +8,7 @@
*/
package dev.zontreck.engineerdecor.blocks;
import dev.zontreck.libzontreck.edlibmc.StandardBlocks;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.InteractionHand;
@ -26,7 +27,6 @@ import net.minecraft.world.level.material.Fluids;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
import dev.zontreck.engineerdecor.libmc.StandardBlocks;
import javax.annotation.Nullable;
import java.util.ArrayList;
@ -34,24 +34,25 @@ import java.util.Collections;
import java.util.List;
public class EdgeAlignedRailingBlock extends StandardBlocks.HorizontalFourWayWaterLoggable
{
public EdgeAlignedRailingBlock(long config, BlockBehaviour.Properties properties, final AABB base_aabb, final AABB railing_aabb)
{ super(config, properties, base_aabb, railing_aabb, 0); }
public class EdgeAlignedRailingBlock extends StandardBlocks.HorizontalFourWayWaterLoggable {
public EdgeAlignedRailingBlock(long config, BlockBehaviour.Properties properties, final AABB base_aabb, final AABB railing_aabb) {
super(config, properties, base_aabb, railing_aabb, 0);
}
@Override
public boolean propagatesSkylightDown(BlockState state, BlockGetter reader, BlockPos pos)
{ return true; }
public boolean propagatesSkylightDown(BlockState state, BlockGetter reader, BlockPos pos) {
return true;
}
@Override
@SuppressWarnings("deprecation")
public boolean canBeReplaced(BlockState state, BlockPlaceContext useContext)
{ return (useContext.getItemInHand().getItem() == asItem()) || super.canBeReplaced(state, useContext); }
public boolean canBeReplaced(BlockState state, BlockPlaceContext useContext) {
return (useContext.getItemInHand().getItem() == asItem()) || super.canBeReplaced(state, useContext);
}
@Override
@Nullable
public BlockState getStateForPlacement(BlockPlaceContext context)
{
public BlockState getStateForPlacement(BlockPlaceContext context) {
if (context.getClickedFace() != Direction.UP) return null;
BlockState state = context.getLevel().getBlockState(context.getClickedPos());
if (state.getBlock() != this) state = super.getStateForPlacement(context);
@ -62,13 +63,13 @@ public class EdgeAlignedRailingBlock extends StandardBlocks.HorizontalFourWayWat
@Override
@SuppressWarnings("deprecation")
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit)
{
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
if (player.getItemInHand(hand).getItem() != asItem()) return InteractionResult.PASS;
Direction face = hit.getDirection();
if (!face.getAxis().isHorizontal()) return InteractionResult.sidedSuccess(world.isClientSide());
final Vec3 rhv = hit.getLocation().subtract(Vec3.atCenterOf(hit.getBlockPos()));
if(rhv.multiply(Vec3.atLowerCornerOf(face.getNormal())).scale(2).lengthSqr() < 0.99) face = face.getOpposite(); // click on railing, not the outer side.
if (rhv.multiply(Vec3.atLowerCornerOf(face.getNormal())).scale(2).lengthSqr() < 0.99)
face = face.getOpposite(); // click on railing, not the outer side.
BooleanProperty railing = getDirectionProperty(face);
boolean add = (!state.getValue(railing));
state = state.setValue(railing, add);
@ -84,12 +85,12 @@ public class EdgeAlignedRailingBlock extends StandardBlocks.HorizontalFourWayWat
// -- IDecorBlock
@Override
public boolean hasDynamicDropList()
{ return true; }
public boolean hasDynamicDropList() {
return true;
}
@Override
public List<ItemStack> dropList(BlockState state, Level world, @Nullable BlockEntity te, boolean explosion)
{
public List<ItemStack> dropList(BlockState state, Level world, @Nullable BlockEntity te, boolean explosion) {
if (world.isClientSide()) return Collections.singletonList(ItemStack.EMPTY);
List<ItemStack> drops = new ArrayList<>();
int n = (state.getValue(NORTH) ? 1 : 0) + (state.getValue(EAST) ? 1 : 0) + (state.getValue(SOUTH) ? 1 : 0) + (state.getValue(WEST) ? 1 : 0);

View file

@ -0,0 +1,16 @@
package dev.zontreck.engineerdecor.datagen;
import dev.zontreck.engineerdecor.ModEngineersDecor;
import net.minecraftforge.data.event.GatherDataEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
@Mod.EventBusSubscriber(modid = ModEngineersDecor.MODID, bus = Mod.EventBusSubscriber.Bus.MOD)
public class ModDatagen
{
@SubscribeEvent
public static void onDatagen(GatherDataEvent ev)
{
}
}

View file

@ -23,35 +23,37 @@ import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
public class ModRenderers
{
public class ModRenderers {
//--------------------------------------------------------------------------------------------------------------------
// InvisibleEntityRenderer
//--------------------------------------------------------------------------------------------------------------------
@OnlyIn(Dist.CLIENT)
public static class InvisibleEntityRenderer<T extends Entity> extends EntityRenderer<T>
{
public static class InvisibleEntityRenderer<T extends Entity> extends EntityRenderer<T> {
private final Minecraft mc = Minecraft.getInstance();
public InvisibleEntityRenderer(EntityRendererProvider.Context context)
{ super(context); }
public InvisibleEntityRenderer(EntityRendererProvider.Context context) {
super(context);
}
public void render(T entity, float entityYaw, float partialTicks, PoseStack matrixStack, MultiBufferSource buffer, int packedLight)
{}
public void render(T entity, float entityYaw, float partialTicks, PoseStack matrixStack, MultiBufferSource buffer, int packedLight) {
}
public Vec3 getRenderOffset(T entity, float partialTicks)
{ return Vec3.ZERO; }
public Vec3 getRenderOffset(T entity, float partialTicks) {
return Vec3.ZERO;
}
@SuppressWarnings("deprecation")
public ResourceLocation getTextureLocation(T entity)
{ return TextureAtlas.LOCATION_BLOCKS; }
public ResourceLocation getTextureLocation(T entity) {
return TextureAtlas.LOCATION_BLOCKS;
}
protected boolean shouldShowName(T entity)
{ return false; }
protected boolean shouldShowName(T entity) {
return false;
}
protected void renderNameTag(T entity, Component displayName, PoseStack matrixStack, MultiBufferSource buffer, int packedLight)
{}
protected void renderNameTag(T entity, Component displayName, PoseStack matrixStack, MultiBufferSource buffer, int packedLight) {
}
}
}

View file

@ -9,6 +9,7 @@
package dev.zontreck.engineerdecor.detail;
import com.google.common.collect.ImmutableList;
import dev.zontreck.libzontreck.edlibmc.Auxiliaries;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Vec3i;
import net.minecraft.resources.ResourceLocation;
@ -20,18 +21,20 @@ import net.minecraft.world.level.block.LeavesBlock;
import net.minecraft.world.level.block.VineBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.registries.ForgeRegistries;
import dev.zontreck.engineerdecor.libmc.Auxiliaries;
import java.util.*;
import java.util.stream.Collectors;
public class TreeCutting
{
public class TreeCutting {
private static final Set<Block> universal_logs_ = new HashSet<>();
private static final List<Vec3i> hoffsets = ImmutableList.of(
new Vec3i(1, 0, 0), new Vec3i(1, 0, 1), new Vec3i(0, 0, 1),
new Vec3i(-1, 0, 1), new Vec3i(-1, 0, 0), new Vec3i(-1, 0, -1),
new Vec3i(0, 0, -1), new Vec3i(1, 0, -1)
);
public static void on_config(List<String> universal_logs)
{
public static void on_config(List<String> universal_logs) {
universal_logs_.clear();
if (universal_logs.isEmpty()) return;
try {
@ -48,36 +51,29 @@ public class TreeCutting
}
}
public static boolean canChop(Level world, BlockState state, BlockPos pos)
{ return isLog(state) || (universal_logs_.contains(state.getBlock()) && isLog(world.getBlockState(pos.above()))); }
// -------------------------------------------------------------------------------------------------------------------
private static final List<Vec3i> hoffsets = ImmutableList.of(
new Vec3i( 1,0, 0), new Vec3i( 1,0, 1), new Vec3i( 0,0, 1),
new Vec3i(-1,0, 1), new Vec3i(-1,0, 0), new Vec3i(-1,0,-1),
new Vec3i( 0,0,-1), new Vec3i( 1,0,-1)
);
public static boolean canChop(Level world, BlockState state, BlockPos pos) {
return isLog(state) || (universal_logs_.contains(state.getBlock()) && isLog(world.getBlockState(pos.above())));
}
private static boolean isLog(BlockState state)
{ return (state.is(BlockTags.LOGS)); }
private static boolean isLog(BlockState state) {
return (state.is(BlockTags.LOGS));
}
private static boolean isSameLog(BlockState a, BlockState b)
{
private static boolean isSameLog(BlockState a, BlockState b) {
final Block ba = a.getBlock();
final Block bb = b.getBlock();
return (ba == bb) || (universal_logs_.contains(ba) && isLog(b)) || (universal_logs_.contains(bb) && isLog(a)) || (universal_logs_.contains(ba) && universal_logs_.contains(bb));
}
private static boolean isLeaves(BlockState state)
{
private static boolean isLeaves(BlockState state) {
if (state.getBlock() instanceof LeavesBlock) return true;
if (state.is(BlockTags.LEAVES)) return true;
return false;
}
private static List<BlockPos> findBlocksAround(final Level world, final BlockPos centerPos, final BlockState leaf_type_state, final Set<BlockPos> checked, int recursion_left)
{
private static List<BlockPos> findBlocksAround(final Level world, final BlockPos centerPos, final BlockState leaf_type_state, final Set<BlockPos> checked, int recursion_left) {
ArrayList<BlockPos> to_decay = new ArrayList<>();
for (int y = -1; y <= 1; ++y) {
final BlockPos layer = centerPos.offset(0, y, 0);
@ -95,16 +91,15 @@ public class TreeCutting
return to_decay;
}
private static void breakBlock(Level world, BlockPos pos)
{
private static void breakBlock(Level world, BlockPos pos) {
Block.dropResources(world.getBlockState(pos), world, pos);
world.setBlock(pos, world.getFluidState(pos).createLegacyBlock(), 1 | 2 | 8);
}
public static int chopTree(Level world, BlockState broken_state, BlockPos startPos, int max_blocks_to_break, boolean without_target_block)
{
public static int chopTree(Level world, BlockState broken_state, BlockPos startPos, int max_blocks_to_break, boolean without_target_block) {
if (world.isClientSide) return 0;
if(universal_logs_.contains(broken_state.getBlock())) broken_state = world.getBlockState(startPos.above()); // For safe detection, at least the block above must be a normal log block.
if (universal_logs_.contains(broken_state.getBlock()))
broken_state = world.getBlockState(startPos.above()); // For safe detection, at least the block above must be a normal log block.
if (!isLog(broken_state)) return 0;
final long ymin = startPos.getY();
final long max_leaf_distance = 8;
@ -158,7 +153,8 @@ public class TreeCutting
final BlockPos p = pos.offset(v);
if (checked.contains(p)) continue;
checked.add(p);
if(p.distSqr(new BlockPos(startPos.getX(), p.getY(), startPos.getZ())) > (cutlevel > 2 ? 256 : 9)) continue;
if (p.distSqr(new BlockPos(startPos.getX(), p.getY(), startPos.getZ())) > (cutlevel > 2 ? 256 : 9))
continue;
final BlockState st = world.getBlockState(p);
final Block bl = st.getBlock();
if (isSameLog(st, broken_state)) {

View file

@ -8,7 +8,8 @@
*/
package dev.zontreck.engineerdecor.eapi.jei;
public class JEIPlugin {}
public class JEIPlugin {
}
/*
import mezz.jei.api.constants.RecipeTypes;

View file

@ -8,35 +8,26 @@
*/
package dev.zontreck.engineerdecor.items;
import dev.zontreck.libzontreck.edlibmc.Auxiliaries;
import net.minecraft.network.chat.Component;
import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.level.Level;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import dev.zontreck.engineerdecor.ModConfig;
import dev.zontreck.engineerdecor.libmc.Auxiliaries;
import dev.zontreck.engineerdecor.libmc.Registries;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class EdItem extends Item
{
public EdItem(Item.Properties properties)
{ super(properties.tab(Registries.getCreativeModeTab())); }
public class EdItem extends Item {
public EdItem(Item.Properties properties) {
super(properties);
}
@Override
@OnlyIn(Dist.CLIENT)
public void appendHoverText(ItemStack stack, @Nullable Level world, List<Component> tooltip, TooltipFlag flag)
{ Auxiliaries.Tooltip.addInformation(stack, world, tooltip, flag, true); }
@Override
public Collection<CreativeModeTab> getCreativeTabs()
{ return ModConfig.isOptedOut(this) ? (new ArrayList<>()) : (Collections.singletonList(Registries.getCreativeModeTab())); }
public void appendHoverText(ItemStack stack, @Nullable Level world, List<Component> tooltip, TooltipFlag flag) {
Auxiliaries.Tooltip.addInformation(stack, world, tooltip, flag, true);
}
}