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.blocks.*;
import dev.zontreck.engineerdecor.detail.TreeCutting; import dev.zontreck.engineerdecor.detail.TreeCutting;
import dev.zontreck.engineerdecor.libmc.Auxiliaries; import dev.zontreck.libzontreck.edlibmc.Auxiliaries;
import dev.zontreck.engineerdecor.libmc.OptionalRecipeCondition; import dev.zontreck.libzontreck.edlibmc.OptionalRecipeCondition;
import dev.zontreck.engineerdecor.libmc.SlabSliceBlock; import dev.zontreck.libzontreck.edlibmc.SlabSliceBlock;
import dev.zontreck.engineerdecor.libmc.VariantSlabBlock; import dev.zontreck.libzontreck.edlibmc.VariantSlabBlock;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraftforge.common.ForgeConfigSpec; import net.minecraftforge.common.ForgeConfigSpec;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import wile.engineersdecor.blocks.*;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.*; import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
public class ModConfig public class ModConfig {
{
//--------------------------------------------------------------------------------------------------------------------
private static final String MODID = ModEngineersDecor.MODID;
public static final CommonConfig COMMON; public static final CommonConfig COMMON;
public static final ServerConfig SERVER; public static final ServerConfig SERVER;
public static final ForgeConfigSpec COMMON_CONFIG_SPEC; public static final ForgeConfigSpec COMMON_CONFIG_SPEC;
public static final ForgeConfigSpec SERVER_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 { static {
final Pair<CommonConfig, ForgeConfigSpec> common_ = (new ForgeConfigSpec.Builder()).configure(CommonConfig::new); final Pair<CommonConfig, ForgeConfigSpec> common_ = (new ForgeConfigSpec.Builder()).configure(CommonConfig::new);
@ -44,10 +60,161 @@ public class ModConfig
SERVER = server_.getLeft(); 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 // Optout
public final ForgeConfigSpec.ConfigValue<String> pattern_excludes; public final ForgeConfigSpec.ConfigValue<String> pattern_excludes;
public final ForgeConfigSpec.ConfigValue<String> pattern_includes; 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_config_logging;
public final ForgeConfigSpec.BooleanValue with_debug_logging; public final ForgeConfigSpec.BooleanValue with_debug_logging;
CommonConfig(ForgeConfigSpec.Builder builder) CommonConfig(ForgeConfigSpec.Builder builder) {
{
builder.comment("Settings affecting the logical server side.") builder.comment("Settings affecting the logical server side.")
.push("server"); .push("server");
// --- OPTOUTS ------------------------------------------------------------ // --- OPTOUTS ------------------------------------------------------------
@ -109,10 +275,7 @@ public class ModConfig
} }
} }
//-------------------------------------------------------------------------------------------------------------------- public static class ServerConfig {
public static class ServerConfig
{
// Optout // Optout
public final ForgeConfigSpec.BooleanValue without_chair_sitting; public final ForgeConfigSpec.BooleanValue without_chair_sitting;
public final ForgeConfigSpec.BooleanValue without_mob_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_energy_consumption;
public final ForgeConfigSpec.IntValue milking_machine_milking_delay; public final ForgeConfigSpec.IntValue milking_machine_milking_delay;
ServerConfig(ForgeConfigSpec.Builder builder) ServerConfig(ForgeConfigSpec.Builder builder) {
{
builder.comment("Settings affecting the logical server side.") builder.comment("Settings affecting the logical server side.")
.push("server"); .push("server");
// --- OPTOUTS ------------------------------------------------------------ // --- 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.blocks.*;
import dev.zontreck.engineerdecor.detail.ModRenderers; import dev.zontreck.engineerdecor.detail.ModRenderers;
import dev.zontreck.engineerdecor.items.EdItem; 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.gui.screens.MenuScreens;
import net.minecraft.client.renderer.entity.EntityRenderers; import net.minecraft.client.renderer.entity.EntityRenderers;
import net.minecraft.core.BlockPos; 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.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockBehaviour; import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState; 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.AABB;
import net.minecraft.world.phys.shapes.BooleanOp; import net.minecraft.world.phys.shapes.BooleanOp;
import net.minecraft.world.phys.shapes.Shapes; 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.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import wile.engineersdecor.blocks.*;
import wile.engineersdecor.libmc.*;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.ArrayList; import java.util.ArrayList;
@ -52,15 +48,8 @@ import java.util.List;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class ModContent public class ModContent {
{ public static void init(String modid) {
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)
{
detail.MODID = modid; detail.MODID = modid;
initTags(); initTags();
initBlocks(); initBlocks();
@ -68,46 +57,44 @@ public class ModContent
initEntities(); initEntities();
} }
public static void initTags() public static void initTags() {
{
Registries.addOptionalBlockTag("accepted_mineral_smelter_input", new ResourceLocation("minecraft", "diorite"), new ResourceLocation("minecraft", "cobblestone")); 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( Registries.addBlock("clinker_brick_block", () -> new StandardBlocks.BaseBlock(
StandardBlocks.CFG_DEFAULT, 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( Registries.addBlock("clinker_brick_slab", () -> new VariantSlabBlock(
StandardBlocks.CFG_DEFAULT, 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( Registries.addBlock("clinker_brick_stairs", () -> new StandardStairsBlock(
StandardBlocks.CFG_DEFAULT, StandardBlocks.CFG_DEFAULT,
() -> Registries.getBlock("clinker_brick_block").defaultBlockState(), () -> 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( Registries.addBlock("clinker_brick_wall", () -> new EdWallBlock(
StandardBlocks.CFG_DEFAULT, 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( Registries.addBlock("clinker_brick_stained_block", () -> new StandardBlocks.BaseBlock(
StandardBlocks.CFG_DEFAULT, 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( Registries.addBlock("clinker_brick_stained_slab", () -> new VariantSlabBlock(
StandardBlocks.CFG_DEFAULT, 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( Registries.addBlock("clinker_brick_stained_stairs", () -> new StandardStairsBlock(
StandardBlocks.CFG_DEFAULT, StandardBlocks.CFG_DEFAULT,
() -> Registries.getBlock("clinker_brick_stained_block").defaultBlockState(), () -> 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( Registries.addBlock("clinker_brick_sastor_corner_block", () -> new EdCornerOrnamentedBlock(
StandardBlocks.CFG_DEFAULT, 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[]{ new Block[]{
Registries.getBlock("clinker_brick_block"), Registries.getBlock("clinker_brick_block"),
Registries.getBlock("clinker_brick_slab"), Registries.getBlock("clinker_brick_slab"),
@ -119,7 +106,7 @@ public class ModContent
)); ));
Registries.addBlock("clinker_brick_recessed", () -> new StandardBlocks.HorizontalWaterLoggable( Registries.addBlock("clinker_brick_recessed", () -> new StandardBlocks.HorizontalWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_LOOK_PLACEMENT, 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[]{ new AABB[]{
Auxiliaries.getPixeledAABB(3, 0, 0, 13, 16, 1), Auxiliaries.getPixeledAABB(3, 0, 0, 13, 16, 1),
Auxiliaries.getPixeledAABB(0, 0, 1, 16, 16, 11), Auxiliaries.getPixeledAABB(0, 0, 1, 16, 16, 11),
@ -128,7 +115,7 @@ public class ModContent
)); ));
Registries.addBlock("clinker_brick_vertically_slit", () -> new StandardBlocks.HorizontalWaterLoggable( Registries.addBlock("clinker_brick_vertically_slit", () -> new StandardBlocks.HorizontalWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_LOOK_PLACEMENT, 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[]{ new AABB[]{
Auxiliaries.getPixeledAABB(3, 0, 0, 13, 16, 1), Auxiliaries.getPixeledAABB(3, 0, 0, 13, 16, 1),
Auxiliaries.getPixeledAABB(3, 0, 15, 13, 16, 16), 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( Registries.addBlock("clinker_brick_vertical_slab_structured", () -> new StandardBlocks.HorizontalWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_LOOK_PLACEMENT, 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[]{ new AABB[]{
Auxiliaries.getPixeledAABB(0, 0, 0, 16, 16, 8), Auxiliaries.getPixeledAABB(0, 0, 0, 16, 16, 8),
} }
@ -147,96 +134,96 @@ public class ModContent
Registries.addBlock("slag_brick_block", () -> new StandardBlocks.BaseBlock( Registries.addBlock("slag_brick_block", () -> new StandardBlocks.BaseBlock(
StandardBlocks.CFG_DEFAULT, 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( Registries.addBlock("slag_brick_slab", () -> new VariantSlabBlock(
StandardBlocks.CFG_DEFAULT, 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( Registries.addBlock("slag_brick_stairs", () -> new StandardStairsBlock(
StandardBlocks.CFG_DEFAULT, StandardBlocks.CFG_DEFAULT,
() -> Registries.getBlock("slag_brick_block").defaultBlockState(), () -> 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( Registries.addBlock("slag_brick_wall", () -> new EdWallBlock(
StandardBlocks.CFG_DEFAULT, 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( Registries.addBlock("rebar_concrete", () -> new StandardBlocks.BaseBlock(
StandardBlocks.CFG_DEFAULT, 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( Registries.addBlock("rebar_concrete_slab", () -> new VariantSlabBlock(
StandardBlocks.CFG_DEFAULT, 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( Registries.addBlock("rebar_concrete_stairs", () -> new StandardStairsBlock(
StandardBlocks.CFG_DEFAULT, StandardBlocks.CFG_DEFAULT,
() -> Registries.getBlock("rebar_concrete").defaultBlockState(), () -> 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( Registries.addBlock("rebar_concrete_wall", () -> new EdWallBlock(
StandardBlocks.CFG_DEFAULT, 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( Registries.addBlock("halfslab_rebar_concrete", () -> new SlabSliceBlock(
StandardBlocks.CFG_CUTOUT, 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( Registries.addBlock("rebar_concrete_tile", () -> new StandardBlocks.BaseBlock(
StandardBlocks.CFG_DEFAULT, 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( Registries.addBlock("rebar_concrete_tile_slab", () -> new VariantSlabBlock(
StandardBlocks.CFG_DEFAULT, 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( Registries.addBlock("rebar_concrete_tile_stairs", () -> new StandardStairsBlock(
StandardBlocks.CFG_DEFAULT, StandardBlocks.CFG_DEFAULT,
() -> Registries.getBlock("rebar_concrete_tile").defaultBlockState(), () -> 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( Registries.addBlock("panzerglass_block", () -> new EdGlassBlock(
StandardBlocks.CFG_TRANSLUCENT, 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( Registries.addBlock("panzerglass_slab", () -> new VariantSlabBlock(
StandardBlocks.CFG_TRANSLUCENT, 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( Registries.addBlock("dark_shingle_roof", () -> new EdRoofBlock(
StandardBlocks.CFG_CUTOUT, 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( Registries.addBlock("dark_shingle_roof_metallized", () -> new EdRoofBlock(
StandardBlocks.CFG_CUTOUT, 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( Registries.addBlock("dark_shingle_roof_skylight", () -> new EdRoofBlock(
StandardBlocks.CFG_TRANSLUCENT, 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( Registries.addBlock("dark_shingle_roof_chimneytrunk", () -> new EdChimneyTrunkBlock(
StandardBlocks.CFG_CUTOUT, 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(3, 0, 3, 13, 16, 13)),
Shapes.create(Auxiliaries.getPixeledAABB(5, 0, 5, 11, 16, 11)) Shapes.create(Auxiliaries.getPixeledAABB(5, 0, 5, 11, 16, 11))
)); ));
Registries.addBlock("dark_shingle_roof_wireconduit", () -> new EdChimneyTrunkBlock( Registries.addBlock("dark_shingle_roof_wireconduit", () -> new EdChimneyTrunkBlock(
StandardBlocks.CFG_CUTOUT, 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.join(
Shapes.create(Auxiliaries.getPixeledAABB(3, 0, 3, 13, 13, 13)), Shapes.create(Auxiliaries.getPixeledAABB(3, 0, 3, 13, 13, 13)),
Shapes.create(Auxiliaries.getPixeledAABB(5, 13, 5, 11, 16, 11)), 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( Registries.addBlock("dark_shingle_roof_chimney", () -> new EdChimneyBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_AI_PASSABLE, 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) Auxiliaries.getPixeledAABB(3, 0, 3, 13, 6, 13)
)); ));
Registries.addBlock("dark_shingle_roof_block", () -> new StandardBlocks.BaseBlock( Registries.addBlock("dark_shingle_roof_block", () -> new StandardBlocks.BaseBlock(
StandardBlocks.CFG_DEFAULT, 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( Registries.addBlock("dark_shingle_roof_slab", () -> new VariantSlabBlock(
StandardBlocks.CFG_DEFAULT, 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( Registries.addBlock("dense_grit_sand_block", () -> new StandardBlocks.BaseBlock(
StandardBlocks.CFG_DEFAULT, 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( Registries.addBlock("dense_grit_dirt_block", () -> new StandardBlocks.BaseBlock(
StandardBlocks.CFG_DEFAULT, 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( Registries.addBlock("dark_shingle_roof_slabslice", () -> new SlabSliceBlock(
StandardBlocks.CFG_DEFAULT, 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( Registries.addBlock("metal_rung_ladder", () -> new EdLadderBlock(
StandardBlocks.CFG_DEFAULT, 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( Registries.addBlock("metal_rung_steps", () -> new EdLadderBlock(
StandardBlocks.CFG_DEFAULT, 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( Registries.addBlock("iron_hatch", () -> new EdHatchBlock(
StandardBlocks.CFG_LOOK_PLACEMENT, 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, 3, 16)},
new AABB[]{ new AABB[]{
Auxiliaries.getPixeledAABB(0, 0, 0, 16, 16, 3), Auxiliaries.getPixeledAABB(0, 0, 0, 16, 16, 3),
@ -300,56 +287,38 @@ public class ModContent
)); ));
Registries.addBlock("metal_sliding_door", () -> new StandardDoorBlock( Registries.addBlock("metal_sliding_door", () -> new StandardDoorBlock(
StandardBlocks.CFG_TRANSLUCENT | StandardBlocks.CFG_HORIZIONTAL, StandardBlocks.CFG_TRANSLUCENT | StandardBlocks.CFG_HORIZIONTAL,
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()
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
)); ));
// ------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------
Registries.addBlock("old_industrial_wood_planks", () -> new StandardBlocks.BaseBlock( Registries.addBlock("old_industrial_wood_planks", () -> new StandardBlocks.BaseBlock(
StandardBlocks.CFG_DEFAULT, 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( Registries.addBlock("old_industrial_wood_slab", () -> new VariantSlabBlock(
StandardBlocks.CFG_DEFAULT, 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( Registries.addBlock("old_industrial_wood_stairs", () -> new StandardStairsBlock(
StandardBlocks.CFG_DEFAULT, StandardBlocks.CFG_DEFAULT,
() -> Registries.getBlock("old_industrial_wood_planks").defaultBlockState(), () -> 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( Registries.addBlock("old_industrial_wood_slabslice", () -> new SlabSliceBlock(
StandardBlocks.CFG_CUTOUT, 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( Registries.addBlock("old_industrial_wood_door", () -> new StandardDoorBlock(
StandardBlocks.CFG_DEFAULT, StandardBlocks.CFG_DEFAULT,
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()
Auxiliaries.getPixeledAABB(15,0, 0, 16,16,16),
Auxiliaries.getPixeledAABB( 0,0,13, 16,16,16),
SoundEvents.WOODEN_DOOR_OPEN, SoundEvents.WOODEN_DOOR_CLOSE
)); ));
// ------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------
Registries.addBlock("treated_wood_stool", () -> new EdChair.ChairBlock( Registries.addBlock("treated_wood_stool", () -> new EdChair.ChairBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_LOOK_PLACEMENT, 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[]{ new AABB[]{
Auxiliaries.getPixeledAABB(4, 7, 4, 12, 8.8, 12), Auxiliaries.getPixeledAABB(4, 7, 4, 12, 8.8, 12),
Auxiliaries.getPixeledAABB(7, 0, 7, 9, 7, 9), Auxiliaries.getPixeledAABB(7, 0, 7, 9, 7, 9),
@ -362,7 +331,7 @@ public class ModContent
Registries.addBlock("iron_inset_light", () -> new StandardBlocks.DirectedWaterLoggable( Registries.addBlock("iron_inset_light", () -> new StandardBlocks.DirectedWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_OPPOSITE_PLACEMENT | StandardBlocks.CFG_AI_PASSABLE, 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[]{ new AABB[]{
Auxiliaries.getPixeledAABB(5, 7, 0, 11, 9, 0.375), Auxiliaries.getPixeledAABB(5, 7, 0, 11, 9, 0.375),
Auxiliaries.getPixeledAABB(6, 6, 0, 10, 10, 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( Registries.addBlock("iron_floor_edge_light", () -> new StandardBlocks.DirectedWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_LOOK_PLACEMENT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_AI_PASSABLE, 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) Auxiliaries.getPixeledAABB(5, 0, 0, 11, 1.8125, 0.375)
)); ));
Registries.addBlock("iron_ceiling_edge_light", () -> new StandardBlocks.DirectedWaterLoggable( Registries.addBlock("iron_ceiling_edge_light", () -> new StandardBlocks.DirectedWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_LOOK_PLACEMENT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_AI_PASSABLE, 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[]{ new AABB[]{
Auxiliaries.getPixeledAABB(0, 15.5, 0, 16, 16, 2.0), Auxiliaries.getPixeledAABB(0, 15.5, 0, 16, 16, 2.0),
Auxiliaries.getPixeledAABB(0, 14.0, 0, 16, 16, 0.5), 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( Registries.addBlock("iron_bulb_light", () -> new StandardBlocks.DirectedWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_OPPOSITE_PLACEMENT | StandardBlocks.CFG_AI_PASSABLE, 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[]{ new AABB[]{
Auxiliaries.getPixeledAABB(6.5, 6.5, 1, 9.5, 9.5, 4), 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) 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( Registries.addBlock("steel_table", () -> new StandardBlocks.WaterLoggable(
StandardBlocks.CFG_CUTOUT, 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) Auxiliaries.getPixeledAABB(0, 0, 0, 16, 16, 16)
)); ));
Registries.addBlock("steel_floor_grating", () -> new EdFloorGratingBlock( Registries.addBlock("steel_floor_grating", () -> new EdFloorGratingBlock(
StandardBlocks.CFG_CUTOUT, 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) Auxiliaries.getPixeledAABB(0, 14, 0, 16, 15.5, 16)
)); ));
@ -410,7 +379,7 @@ public class ModContent
Registries.addBlock("steel_framed_window", () -> new EdWindowBlock( Registries.addBlock("steel_framed_window", () -> new EdWindowBlock(
StandardBlocks.CFG_LOOK_PLACEMENT, 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) Auxiliaries.getPixeledAABB(0, 0, 7.5, 16, 16, 8.5)
)); ));
@ -418,49 +387,49 @@ public class ModContent
Registries.addBlock("treated_wood_pole", () -> new EdStraightPoleBlock( Registries.addBlock("treated_wood_pole", () -> new EdStraightPoleBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_FLIP_PLACEMENT_IF_SAME, 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), Auxiliaries.getPixeledAABB(5.8, 5.8, 0, 10.2, 10.2, 16),
null null
)); ));
Registries.addBlock("treated_wood_pole_head", () -> new EdStraightPoleBlock( Registries.addBlock("treated_wood_pole_head", () -> new EdStraightPoleBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_FLIP_PLACEMENT_IF_SAME, 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), Auxiliaries.getPixeledAABB(5.8, 5.8, 0, 10.2, 10.2, 16),
(EdStraightPoleBlock) Registries.getBlock("treated_wood_pole") // TREATED_WOOD_POLE (EdStraightPoleBlock) Registries.getBlock("treated_wood_pole") // TREATED_WOOD_POLE
)); ));
Registries.addBlock("treated_wood_pole_support", () -> new EdStraightPoleBlock( Registries.addBlock("treated_wood_pole_support", () -> new EdStraightPoleBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_FLIP_PLACEMENT_IF_SAME, 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), Auxiliaries.getPixeledAABB(5.8, 5.8, 0, 10.2, 10.2, 16),
(EdStraightPoleBlock) Registries.getBlock("treated_wood_pole") // TREATED_WOOD_POLE (EdStraightPoleBlock) Registries.getBlock("treated_wood_pole") // TREATED_WOOD_POLE
)); ));
Registries.addBlock("thin_steel_pole", () -> new EdStraightPoleBlock( Registries.addBlock("thin_steel_pole", () -> new EdStraightPoleBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT, 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), Auxiliaries.getPixeledAABB(6, 6, 0, 10, 10, 16),
null null
)); ));
Registries.addBlock("thin_steel_pole_head", () -> new EdStraightPoleBlock( Registries.addBlock("thin_steel_pole_head", () -> new EdStraightPoleBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_FLIP_PLACEMENT_IF_SAME, 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), Auxiliaries.getPixeledAABB(6, 6, 0, 10, 10, 16),
(EdStraightPoleBlock) Registries.getBlock("thin_steel_pole") // THIN_STEEL_POLE (EdStraightPoleBlock) Registries.getBlock("thin_steel_pole") // THIN_STEEL_POLE
)); ));
Registries.addBlock("thick_steel_pole", () -> new EdStraightPoleBlock( Registries.addBlock("thick_steel_pole", () -> new EdStraightPoleBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT, 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), Auxiliaries.getPixeledAABB(5, 5, 0, 11, 11, 16),
null null
)); ));
Registries.addBlock("thick_steel_pole_head", () -> new EdStraightPoleBlock( Registries.addBlock("thick_steel_pole_head", () -> new EdStraightPoleBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_FLIP_PLACEMENT_IF_SAME, 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), Auxiliaries.getPixeledAABB(5, 5, 0, 11, 11, 16),
(EdStraightPoleBlock) Registries.getBlock("thin_steel_pole") (EdStraightPoleBlock) Registries.getBlock("thin_steel_pole")
)); ));
Registries.addBlock("steel_double_t_support", () -> new EdHorizontalSupportBlock( Registries.addBlock("steel_double_t_support", () -> new EdHorizontalSupportBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_LOOK_PLACEMENT, 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(5, 11, 0, 11, 16, 16), // main beam
Auxiliaries.getPixeledAABB(10, 11, 5, 16, 16, 11), // east beam (also for west 180deg) Auxiliaries.getPixeledAABB(10, 11, 5, 16, 16, 11), // east beam (also for west 180deg)
Auxiliaries.getPixeledAABB(6, 0, 6, 10, 16, 10), // down thin Auxiliaries.getPixeledAABB(6, 0, 6, 10, 16, 10), // down thin
@ -471,30 +440,30 @@ public class ModContent
Registries.addBlock("steel_mesh_fence", () -> new EdFenceBlock( Registries.addBlock("steel_mesh_fence", () -> new EdFenceBlock(
StandardBlocks.CFG_CUTOUT, 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 1.5, 16, 0.25, 0, 16, 16
)); ));
Registries.addBlock("steel_mesh_fence_gate", () -> new EdDoubleGateBlock( Registries.addBlock("steel_mesh_fence_gate", () -> new EdDoubleGateBlock(
StandardBlocks.CFG_CUTOUT, 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) Auxiliaries.getPixeledAABB(0, 0, 6.5, 16, 16, 9.5)
)); ));
Registries.addBlock("steel_railing", () -> new EdgeAlignedRailingBlock( Registries.addBlock("steel_railing", () -> new EdgeAlignedRailingBlock(
StandardBlocks.CFG_CUTOUT, 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, 0, 0, 0),
Auxiliaries.getPixeledAABB(0, 0, 0, 16, 15.9, 1) Auxiliaries.getPixeledAABB(0, 0, 0, 16, 15.9, 1)
)); ));
Registries.addBlock("steel_catwalk", () -> new EdCatwalkBlock( Registries.addBlock("steel_catwalk", () -> new EdCatwalkBlock(
StandardBlocks.CFG_CUTOUT, 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, 2, 16),
Auxiliaries.getPixeledAABB(0, 0, 0, 16, 15.9, 1), Auxiliaries.getPixeledAABB(0, 0, 0, 16, 15.9, 1),
Registries.getBlock("steel_railing") Registries.getBlock("steel_railing")
)); ));
Registries.addBlock("steel_catwalk_ta", () -> new EdCatwalkTopAlignedBlock( Registries.addBlock("steel_catwalk_ta", () -> new EdCatwalkTopAlignedBlock(
StandardBlocks.CFG_CUTOUT, 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[]{ new VoxelShape[]{
Shapes.create(Auxiliaries.getPixeledAABB(0, 14, 0, 16, 16, 16)), // only base Shapes.create(Auxiliaries.getPixeledAABB(0, 14, 0, 16, 16, 16)), // only base
Auxiliaries.getUnionShape( // base with thick pole Auxiliaries.getUnionShape( // base with thick pole
@ -521,7 +490,7 @@ public class ModContent
)); ));
Registries.addBlock("steel_catwalk_stairs", () -> new EdCatwalkStairsBlock( Registries.addBlock("steel_catwalk_stairs", () -> new EdCatwalkStairsBlock(
StandardBlocks.CFG_CUTOUT, 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 new AABB[]{ // base
Auxiliaries.getPixeledAABB(1, 2, 8, 15, 4, 16), Auxiliaries.getPixeledAABB(1, 2, 8, 15, 4, 16),
Auxiliaries.getPixeledAABB(1, 10, 0, 15, 12, 8), Auxiliaries.getPixeledAABB(1, 10, 0, 15, 12, 8),
@ -550,67 +519,67 @@ public class ModContent
Registries.addBlock("sign_decor", () -> new StandardBlocks.DirectedWaterLoggable( Registries.addBlock("sign_decor", () -> new StandardBlocks.DirectedWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_AI_PASSABLE, 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) Auxiliaries.getPixeledAABB(0, 0, 15.6, 16, 16, 16.0)
)); ));
Registries.addBlock("sign_hotwire", () -> new StandardBlocks.DirectedWaterLoggable( Registries.addBlock("sign_hotwire", () -> new StandardBlocks.DirectedWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_AI_PASSABLE, 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) Auxiliaries.getPixeledAABB(2, 2, 15.6, 14, 14, 16)
)); ));
Registries.addBlock("sign_danger", () -> new StandardBlocks.DirectedWaterLoggable( Registries.addBlock("sign_danger", () -> new StandardBlocks.DirectedWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_AI_PASSABLE, 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) Auxiliaries.getPixeledAABB(2, 2, 15.6, 14, 14, 16)
)); ));
Registries.addBlock("sign_radioactive", () -> new StandardBlocks.DirectedWaterLoggable( Registries.addBlock("sign_radioactive", () -> new StandardBlocks.DirectedWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_AI_PASSABLE, 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) Auxiliaries.getPixeledAABB(2, 2, 15.6, 14, 14, 16)
)); ));
Registries.addBlock("sign_laser", () -> new StandardBlocks.DirectedWaterLoggable( Registries.addBlock("sign_laser", () -> new StandardBlocks.DirectedWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_AI_PASSABLE, 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) Auxiliaries.getPixeledAABB(2, 2, 15.6, 14, 14, 16)
)); ));
Registries.addBlock("sign_caution", () -> new StandardBlocks.DirectedWaterLoggable( Registries.addBlock("sign_caution", () -> new StandardBlocks.DirectedWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_AI_PASSABLE, 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) Auxiliaries.getPixeledAABB(2, 2, 15.6, 14, 14, 16)
)); ));
Registries.addBlock("sign_magichazard", () -> new StandardBlocks.DirectedWaterLoggable( Registries.addBlock("sign_magichazard", () -> new StandardBlocks.DirectedWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_AI_PASSABLE, 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) Auxiliaries.getPixeledAABB(2, 2, 15.6, 14, 14, 16)
)); ));
Registries.addBlock("sign_firehazard", () -> new StandardBlocks.DirectedWaterLoggable( Registries.addBlock("sign_firehazard", () -> new StandardBlocks.DirectedWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_AI_PASSABLE, 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) Auxiliaries.getPixeledAABB(2, 2, 15.6, 14, 14, 16)
)); ));
Registries.addBlock("sign_hotsurface", () -> new StandardBlocks.DirectedWaterLoggable( Registries.addBlock("sign_hotsurface", () -> new StandardBlocks.DirectedWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_AI_PASSABLE, 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) Auxiliaries.getPixeledAABB(2, 2, 15.6, 14, 14, 16)
)); ));
Registries.addBlock("sign_magneticfield", () -> new StandardBlocks.DirectedWaterLoggable( Registries.addBlock("sign_magneticfield", () -> new StandardBlocks.DirectedWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_AI_PASSABLE, 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) Auxiliaries.getPixeledAABB(2, 2, 15.6, 14, 14, 16)
)); ));
Registries.addBlock("sign_frost", () -> new StandardBlocks.DirectedWaterLoggable( Registries.addBlock("sign_frost", () -> new StandardBlocks.DirectedWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_AI_PASSABLE, 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) Auxiliaries.getPixeledAABB(2, 2, 15.6, 14, 14, 16)
)); ));
Registries.addBlock("sign_exit", () -> new StandardBlocks.DirectedWaterLoggable( Registries.addBlock("sign_exit", () -> new StandardBlocks.DirectedWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_AI_PASSABLE, 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) Auxiliaries.getPixeledAABB(3, 7, 15.6, 13, 13, 16)
)); ));
Registries.addBlock("sign_defense", () -> new StandardBlocks.DirectedWaterLoggable( Registries.addBlock("sign_defense", () -> new StandardBlocks.DirectedWaterLoggable(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_AI_PASSABLE, 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) Auxiliaries.getPixeledAABB(2, 2, 15.6, 14, 14, 16)
)); ));
@ -619,19 +588,19 @@ public class ModContent
Registries.addBlock("small_lab_furnace", Registries.addBlock("small_lab_furnace",
() -> new EdFurnace.FurnaceBlock( () -> new EdFurnace.FurnaceBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_LOOK_PLACEMENT | StandardBlocks.CFG_OPPOSITE_PLACEMENT, 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[]{ new AABB[]{
Auxiliaries.getPixeledAABB(1, 0, 1, 15, 1, 15), Auxiliaries.getPixeledAABB(1, 0, 1, 15, 1, 15),
Auxiliaries.getPixeledAABB(0, 1, 1, 16, 16, 16), Auxiliaries.getPixeledAABB(0, 1, 1, 16, 16, 16),
} }
), ),
EdFurnace.FurnaceTileEntity::new, EdFurnace.FurnaceTileEntity::new
EdFurnace.FurnaceContainer::new
); );
Registries.addBlock("small_electrical_furnace", Registries.addBlock("small_electrical_furnace",
() -> new EdElectricalFurnace.ElectricalFurnaceBlock( () -> new EdElectricalFurnace.ElectricalFurnaceBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_LOOK_PLACEMENT | StandardBlocks.CFG_OPPOSITE_PLACEMENT, 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[]{ new AABB[]{
Auxiliaries.getPixeledAABB(0, 0, 0, 16, 11, 16), Auxiliaries.getPixeledAABB(0, 0, 0, 16, 11, 16),
Auxiliaries.getPixeledAABB(1, 11, 0, 15, 12, 16), Auxiliaries.getPixeledAABB(1, 11, 0, 15, 12, 16),
@ -640,35 +609,32 @@ public class ModContent
Auxiliaries.getPixeledAABB(4, 14, 0, 12, 16, 16), Auxiliaries.getPixeledAABB(4, 14, 0, 12, 16, 16),
} }
), ),
EdElectricalFurnace.ElectricalFurnaceTileEntity::new, EdElectricalFurnace.ElectricalFurnaceTileEntity::new
EdElectricalFurnace.ElectricalFurnaceContainer::new
); );
Registries.addBlock("factory_dropper", Registries.addBlock("factory_dropper",
() -> new EdDropper.DropperBlock( () -> new EdDropper.DropperBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_LOOK_PLACEMENT | StandardBlocks.CFG_OPPOSITE_PLACEMENT, 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) Auxiliaries.getPixeledAABB(0, 0, 1, 16, 16, 16)
), ),
EdDropper.DropperTileEntity::new, EdDropper.DropperTileEntity::new
EdDropper.DropperUiContainer::new
); );
Registries.addBlock("factory_placer", Registries.addBlock("factory_placer",
() -> new EdPlacer.PlacerBlock( () -> new EdPlacer.PlacerBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_LOOK_PLACEMENT | StandardBlocks.CFG_FLIP_PLACEMENT_SHIFTCLICK | StandardBlocks.CFG_OPPOSITE_PLACEMENT, 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[]{ new AABB[]{
Auxiliaries.getPixeledAABB(0, 0, 2, 16, 16, 16), Auxiliaries.getPixeledAABB(0, 0, 2, 16, 16, 16),
Auxiliaries.getPixeledAABB(0, 0, 0, 1, 16, 2), Auxiliaries.getPixeledAABB(0, 0, 0, 1, 16, 2),
Auxiliaries.getPixeledAABB(15, 0, 0, 16, 16, 2) Auxiliaries.getPixeledAABB(15, 0, 0, 16, 16, 2)
} }
), ),
EdPlacer.PlacerTileEntity::new, EdPlacer.PlacerTileEntity::new
EdPlacer.PlacerContainer::new
); );
Registries.addBlock("small_block_breaker", Registries.addBlock("small_block_breaker",
() -> new EdBreaker.BreakerBlock( () -> new EdBreaker.BreakerBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_LOOK_PLACEMENT | StandardBlocks.CFG_OPPOSITE_PLACEMENT | StandardBlocks.CFG_FLIP_PLACEMENT_SHIFTCLICK, 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[]{ new AABB[]{
Auxiliaries.getPixeledAABB(1, 0, 0, 15, 4, 7), Auxiliaries.getPixeledAABB(1, 0, 0, 15, 4, 7),
Auxiliaries.getPixeledAABB(1, 0, 7, 15, 12, 16), Auxiliaries.getPixeledAABB(1, 0, 7, 15, 12, 16),
@ -683,7 +649,7 @@ public class ModContent
Registries.addBlock("factory_hopper", Registries.addBlock("factory_hopper",
() -> new EdHopper.HopperBlock( () -> new EdHopper.HopperBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_OPPOSITE_PLACEMENT, 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[]{ final AABB[] down_aabbs = new AABB[]{
Auxiliaries.getPixeledAABB(5, 0, 5, 11, 1, 11), Auxiliaries.getPixeledAABB(5, 0, 5, 11, 1, 11),
Auxiliaries.getPixeledAABB(4, 1, 4, 12, 7, 12), Auxiliaries.getPixeledAABB(4, 1, 4, 12, 7, 12),
@ -726,22 +692,20 @@ public class ModContent
)); ));
} }
), ),
EdHopper.HopperTileEntity::new, EdHopper.HopperTileEntity::new
EdHopper.HopperContainer::new
); );
Registries.addBlock("small_waste_incinerator", Registries.addBlock("small_waste_incinerator",
() -> new EdWasteIncinerator.WasteIncineratorBlock( () -> new EdWasteIncinerator.WasteIncineratorBlock(
StandardBlocks.CFG_DEFAULT, 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) Auxiliaries.getPixeledAABB(0, 0, 0, 16, 16, 16)
), ),
EdWasteIncinerator.WasteIncineratorTileEntity::new, EdWasteIncinerator.WasteIncineratorTileEntity::new
EdWasteIncinerator.WasteIncineratorContainer::new
); );
Registries.addBlock("small_mineral_smelter", Registries.addBlock("small_mineral_smelter",
() -> new EdMineralSmelter.MineralSmelterBlock( () -> new EdMineralSmelter.MineralSmelterBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_LOOK_PLACEMENT, 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) Auxiliaries.getPixeledAABB(1.1, 0, 1.1, 14.9, 16, 14.9)
), ),
EdMineralSmelter.MineralSmelterTileEntity::new EdMineralSmelter.MineralSmelterTileEntity::new
@ -749,7 +713,7 @@ public class ModContent
Registries.addBlock("small_freezer", Registries.addBlock("small_freezer",
() -> new EdFreezer.FreezerBlock( () -> new EdFreezer.FreezerBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_LOOK_PLACEMENT, 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) Auxiliaries.getPixeledAABB(1.1, 0, 1.1, 14.9, 16, 14.9)
), ),
EdFreezer.FreezerTileEntity::new EdFreezer.FreezerTileEntity::new
@ -757,7 +721,7 @@ public class ModContent
Registries.addBlock("small_solar_panel", Registries.addBlock("small_solar_panel",
() -> new EdSolarPanel.SolarPanelBlock( () -> new EdSolarPanel.SolarPanelBlock(
StandardBlocks.CFG_CUTOUT, 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[]{ new AABB[]{
Auxiliaries.getPixeledAABB(0, 0, 0, 16, 2, 16), Auxiliaries.getPixeledAABB(0, 0, 0, 16, 2, 16),
Auxiliaries.getPixeledAABB(6, 1.5, 3, 10, 10.5, 13), Auxiliaries.getPixeledAABB(6, 1.5, 3, 10, 10.5, 13),
@ -768,7 +732,7 @@ public class ModContent
Registries.addBlock("small_milking_machine", Registries.addBlock("small_milking_machine",
() -> new EdMilker.MilkerBlock( () -> new EdMilker.MilkerBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_LOOK_PLACEMENT, 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[]{ new AABB[]{
Auxiliaries.getPixeledAABB(1, 1, 0, 15, 14, 10), Auxiliaries.getPixeledAABB(1, 1, 0, 15, 14, 10),
Auxiliaries.getPixeledAABB(0, 14, 0, 16, 16, 13), Auxiliaries.getPixeledAABB(0, 14, 0, 16, 16, 13),
@ -782,7 +746,7 @@ public class ModContent
Registries.addBlock("small_tree_cutter", Registries.addBlock("small_tree_cutter",
() -> new EdTreeCutter.TreeCutterBlock( () -> new EdTreeCutter.TreeCutterBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_HORIZIONTAL | StandardBlocks.CFG_LOOK_PLACEMENT | StandardBlocks.CFG_FLIP_PLACEMENT_SHIFTCLICK, 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[]{ new AABB[]{
Auxiliaries.getPixeledAABB(0, 0, 0, 16, 3, 16), Auxiliaries.getPixeledAABB(0, 0, 0, 16, 3, 16),
Auxiliaries.getPixeledAABB(0, 3, 0, 3, 8, 16), Auxiliaries.getPixeledAABB(0, 3, 0, 3, 8, 16),
@ -797,7 +761,7 @@ public class ModContent
Registries.addBlock("straight_pipe_valve", () -> new EdPipeValve.PipeValveBlock( Registries.addBlock("straight_pipe_valve", () -> new EdPipeValve.PipeValveBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_OPPOSITE_PLACEMENT | StandardBlocks.CFG_FLIP_PLACEMENT_SHIFTCLICK, StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_OPPOSITE_PLACEMENT | StandardBlocks.CFG_FLIP_PLACEMENT_SHIFTCLICK,
EdPipeValve.CFG_CHECK_VALVE, 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[]{ new AABB[]{
Auxiliaries.getPixeledAABB(2, 2, 0, 14, 14, 2), Auxiliaries.getPixeledAABB(2, 2, 0, 14, 14, 2),
Auxiliaries.getPixeledAABB(2, 2, 14, 14, 14, 16), Auxiliaries.getPixeledAABB(2, 2, 14, 14, 14, 16),
@ -808,7 +772,7 @@ public class ModContent
Registries.addBlock("straight_pipe_valve_redstone", () -> new EdPipeValve.PipeValveBlock( Registries.addBlock("straight_pipe_valve_redstone", () -> new EdPipeValve.PipeValveBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_OPPOSITE_PLACEMENT, StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_OPPOSITE_PLACEMENT,
EdPipeValve.CFG_REDSTONE_CONTROLLED_VALVE, 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[]{ new AABB[]{
Auxiliaries.getPixeledAABB(2, 2, 0, 14, 14, 2), Auxiliaries.getPixeledAABB(2, 2, 0, 14, 14, 2),
Auxiliaries.getPixeledAABB(2, 2, 14, 14, 14, 16), Auxiliaries.getPixeledAABB(2, 2, 14, 14, 14, 16),
@ -820,7 +784,7 @@ public class ModContent
() -> new EdPipeValve.PipeValveBlock( () -> new EdPipeValve.PipeValveBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_OPPOSITE_PLACEMENT, StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_FACING_PLACEMENT | StandardBlocks.CFG_OPPOSITE_PLACEMENT,
EdPipeValve.CFG_REDSTONE_CONTROLLED_VALVE | EdPipeValve.CFG_ANALOG_VALVE, 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[]{ new AABB[]{
Auxiliaries.getPixeledAABB(2, 2, 0, 14, 14, 2), Auxiliaries.getPixeledAABB(2, 2, 0, 14, 14, 2),
Auxiliaries.getPixeledAABB(2, 2, 14, 14, 14, 16), Auxiliaries.getPixeledAABB(2, 2, 14, 14, 14, 16),
@ -836,7 +800,7 @@ public class ModContent
Registries.addBlock("fluid_barrel", Registries.addBlock("fluid_barrel",
() -> new EdFluidBarrel.FluidBarrelBlock( () -> new EdFluidBarrel.FluidBarrelBlock(
StandardBlocks.CFG_CUTOUT | StandardBlocks.CFG_LOOK_PLACEMENT | StandardBlocks.CFG_OPPOSITE_PLACEMENT, 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[]{ new AABB[]{
Auxiliaries.getPixeledAABB(2, 0, 0, 14, 1, 16), Auxiliaries.getPixeledAABB(2, 0, 0, 14, 1, 16),
Auxiliaries.getPixeledAABB(1, 1, 0, 15, 2, 16), Auxiliaries.getPixeledAABB(1, 1, 0, 15, 2, 16),
@ -851,7 +815,7 @@ public class ModContent
Registries.addBlock("small_fluid_funnel", Registries.addBlock("small_fluid_funnel",
() -> new EdFluidFunnel.FluidFunnelBlock( () -> new EdFluidFunnel.FluidFunnelBlock(
StandardBlocks.CFG_CUTOUT, 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[]{ new AABB[]{
Auxiliaries.getPixeledAABB(0, 0, 0, 16, 14, 16), Auxiliaries.getPixeledAABB(0, 0, 0, 16, 14, 16),
Auxiliaries.getPixeledAABB(1, 14, 1, 15, 15, 15), Auxiliaries.getPixeledAABB(1, 14, 1, 15, 15, 15),
@ -866,7 +830,7 @@ public class ModContent
Registries.addBlock("test_block", Registries.addBlock("test_block",
() -> new EdTestBlock.TestBlock( () -> new EdTestBlock.TestBlock(
StandardBlocks.CFG_LOOK_PLACEMENT, 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) Auxiliaries.getPixeledAABB(0, 0, 0, 16, 16, 16)
), ),
EdTestBlock.TestTileEntity::new EdTestBlock.TestTileEntity::new
@ -874,13 +838,11 @@ public class ModContent
} }
public static void initItems() public static void initItems() {
{ Registries.addItem("metal_bar", () -> new EdItem((new Item.Properties())));
Registries.addItem("metal_bar", ()->new EdItem((new Item.Properties()).tab(Registries.getCreativeModeTab())));
} }
public static void initEntities() public static void initEntities() {
{
Registries.addEntityType("et_chair", () -> Registries.addEntityType("et_chair", () ->
EntityType.Builder.of(EdChair.EntityChair::new, MobCategory.MISC) EntityType.Builder.of(EdChair.EntityChair::new, MobCategory.MISC)
.fireImmune().sized(1e-3f, 1e-3f).noSave() .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 // Registry wrappers
//-------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------
public static Block getBlock(String name) public static Item getItem(String name) {
{ return Registries.getBlock(name); } return Registries.getItem(name);
}
public static Item getItem(String name) public static TagKey<Block> getBlockTagKey(String name) {
{ return Registries.getItem(name); } return Registries.getBlockTagKey(name);
}
public static TagKey<Block> getBlockTagKey(String name) public static TagKey<Item> getItemTagKey(String name) {
{ return Registries.getBlockTagKey(name); } return Registries.getItemTagKey(name);
}
public static TagKey<Item> getItemTagKey(String name) public static BlockEntityType<?> getBlockEntityTypeOfBlock(String block_name) {
{ return Registries.getItemTagKey(name); } return Registries.getBlockEntityTypeOfBlock(block_name);
}
public static BlockEntityType<?> getBlockEntityTypeOfBlock(String block_name) public static BlockEntityType<?> getBlockEntityTypeOfBlock(Block block) {
{ return Registries.getBlockEntityTypeOfBlock(block_name); } return Registries.getBlockEntityTypeOfBlock(block);
}
public static BlockEntityType<?> getBlockEntityTypeOfBlock(Block block) public static EntityType<?> getEntityType(String name) {
{ return Registries.getBlockEntityTypeOfBlock(block); } return Registries.getEntityType(name);
}
public static EntityType<?> getEntityType(String name) public static MenuType<?> getMenuType(String block_name) {
{ return Registries.getEntityType(name); } return Registries.getMenuTypeOfBlock(block_name);
}
public static MenuType<?> getMenuType(String block_name)
{ return Registries.getMenuTypeOfBlock(block_name); }
@Nonnull @Nonnull
public static List<Block> getRegisteredBlocks() public static List<Block> getRegisteredBlocks() {
{ return Registries.getRegisteredBlocks(); } return Registries.getRegisteredBlocks();
}
@Nonnull @Nonnull
public static List<Item> getRegisteredItems() public static List<Item> getRegisteredItems() {
{ return Registries.getRegisteredItems(); } return Registries.getRegisteredItems();
}
//--------------------------------------------------------------------------------------------------------------------
// Initialisation events
//--------------------------------------------------------------------------------------------------------------------
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
@SuppressWarnings("unchecked") @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<EdDropper.DropperUiContainer>) Registries.getMenuTypeOfBlock("factory_dropper"), EdDropper.DropperGui::new);
MenuScreens.register((MenuType<EdPlacer.PlacerContainer>) Registries.getMenuTypeOfBlock("factory_placer"), EdPlacer.PlacerGui::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); 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); MenuScreens.register((MenuType<EdWasteIncinerator.WasteIncineratorContainer>) Registries.getMenuTypeOfBlock("small_waste_incinerator"), EdWasteIncinerator.WasteIncineratorGui::new);
} }
//--------------------------------------------------------------------------------------------------------------------
// Initialisation events
//--------------------------------------------------------------------------------------------------------------------
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static void registerBlockEntityRenderers(final FMLClientSetupEvent event) public static void registerBlockEntityRenderers(final FMLClientSetupEvent event) {
{
} }
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public static void processContentClientSide(final FMLClientSetupEvent event) public static void processContentClientSide(final FMLClientSetupEvent event) {
{
// Block renderer selection // Block renderer selection
// Disabled in Forge, model based {"render_type": "cutout"/"translucent"} // Disabled in Forge, model based {"render_type": "cutout"/"translucent"}
// for(Block block: Registries.getRegisteredBlocks()) { // for(Block block: Registries.getRegisteredBlocks()) {
@ -968,4 +937,12 @@ public class ModContent
EntityRenderers.register(Registries.getEntityType("et_chair"), ModRenderers.InvisibleEntityRenderer::new); 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; package dev.zontreck.engineerdecor;
import dev.zontreck.engineerdecor.blocks.EdLadderBlock; 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.minecraft.world.entity.player.Player;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; 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.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import org.slf4j.Logger; 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") @Mod("engineersdecor")
public class ModEngineersDecor public class ModEngineersDecor {
{
public static final String MODID = "engineersdecor"; public static final String MODID = "engineersdecor";
public static final String MODNAME = "Engineer's Decor"; public static final String MODNAME = "Engineer's Decor";
public static final int VERSION_DATAFIXER = 0; public static final int VERSION_DATAFIXER = 0;
private static final Logger LOGGER = com.mojang.logging.LogUtils.getLogger(); private static final Logger LOGGER = com.mojang.logging.LogUtils.getLogger();
public ModEngineersDecor() public ModEngineersDecor() {
{
Auxiliaries.init(MODID, LOGGER, ModConfig::getServerConfig); Auxiliaries.init(MODID, LOGGER, ModConfig::getServerConfig);
Auxiliaries.logGitVersion(MODNAME); 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); ModContent.init(MODID);
OptionalRecipeCondition.init(MODID, LOGGER); OptionalRecipeCondition.init(MODID, LOGGER);
ModLoadingContext.get().registerConfig(net.minecraftforge.fml.config.ModConfig.Type.SERVER, ModConfig.SERVER_CONFIG_SPEC); 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); MinecraftForge.EVENT_BUS.register(this);
} }
private void onSetup(final FMLCommonSetupEvent event) private void onSetup(final FMLCommonSetupEvent event) {
{
CraftingHelper.register(OptionalRecipeCondition.Serializer.INSTANCE); CraftingHelper.register(OptionalRecipeCondition.Serializer.INSTANCE);
Networking.init(MODID); 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); Overlay.TextOverlayGui.on_config(0.75, 0x00ffaa00, 0x55333333, 0x55333333, 0x55444444);
Networking.OverlayTextMessage.setHandler(Overlay.TextOverlayGui::show); Networking.OverlayTextMessage.setHandler(Overlay.TextOverlayGui::show);
ModContent.registerMenuGuis(event); ModContent.registerMenuGuis(event);
@ -59,16 +51,21 @@ public class ModEngineersDecor
ModContent.processContentClientSide(event); ModContent.processContentClientSide(event);
} }
@Mod.EventBusSubscriber(bus=Mod.EventBusSubscriber.Bus.MOD)
public static class ForgeEvents
{
@SubscribeEvent @SubscribeEvent
public static void onConfigLoad(final ModConfigEvent.Loading event) public void onPlayerEvent(final LivingEvent.LivingTickEvent event) {
{ ModConfig.apply(); } 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 @SubscribeEvent
public static void onConfigReload(final ModConfigEvent.Reloading event) public static void onConfigReload(final ModConfigEvent.Reloading event) {
{
try { try {
Auxiliaries.logger().info("Config file changed {}", event.getConfig().getFileName()); Auxiliaries.logger().info("Config file changed {}", event.getConfig().getFileName());
ModConfig.apply(); 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) @OnlyIn(Dist.CLIENT)
@Mod.EventBusSubscriber(Dist.CLIENT) @Mod.EventBusSubscriber(Dist.CLIENT)
public static class ForgeClientEvents public static class ForgeClientEvents {
{
@SubscribeEvent @SubscribeEvent
public static void onRenderGui(net.minecraftforge.client.event.RenderGuiOverlayEvent.Post event) public static void onRenderGui(net.minecraftforge.client.event.RenderGuiOverlayEvent.Post event) {
{ Overlay.TextOverlayGui.INSTANCE.onRenderGui(event.getPoseStack()); } Overlay.TextOverlayGui.INSTANCE.onRenderGui(event.getGuiGraphics());
}
@SubscribeEvent @SubscribeEvent
@OnlyIn(Dist.CLIENT) @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) { if (event.getStage() == net.minecraftforge.client.event.RenderLevelStageEvent.Stage.AFTER_WEATHER) {
Overlay.TextOverlayGui.INSTANCE.onRenderWorldOverlay(event.getPoseStack(), event.getPartialTick()); Overlay.TextOverlayGui.INSTANCE.onRenderWorldOverlay(event.getPoseStack(), event.getPartialTick());
} }

View file

@ -8,6 +8,9 @@
*/ */
package dev.zontreck.engineerdecor.blocks; 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.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.core.particles.ParticleTypes; 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.Level;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks; 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.SoundType;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockBehaviour; 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.capabilities.ForgeCapabilities;
import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.energy.IEnergyStorage; 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 javax.annotation.Nullable;
import java.util.HashSet; import java.util.HashSet;
@ -56,8 +52,7 @@ import java.util.List;
import java.util.Random; import java.util.Random;
public class EdBreaker public class EdBreaker {
{
public static final int BOOST_FACTOR = 8; public static final int BOOST_FACTOR = 8;
public static final int DEFAULT_BOOST_ENERGY = 64; public static final int DEFAULT_BOOST_ENERGY = 64;
public static final int DEFAULT_BREAKING_RELUCTANCE = 17; 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 int min_breaking_time = DEFAULT_MIN_BREAKING_TIME;
private static boolean requires_power = false; 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; final int interval = BreakerTileEntity.TICK_INTERVAL;
boost_energy_consumption = interval * Mth.clamp(boost_energy_per_tick, 4, 4096); boost_energy_consumption = interval * Mth.clamp(boost_energy_per_tick, 4, 4096);
energy_max = Math.max(boost_energy_consumption * 10, 100000); energy_max = Math.max(boost_energy_consumption * 10, 100000);
@ -85,30 +79,33 @@ public class EdBreaker
// Block // 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 static final BooleanProperty ACTIVE = BooleanProperty.create("active");
public BreakerBlock(long config, BlockBehaviour.Properties builder, final AABB[] unrotatedAABBs) public BreakerBlock(long config, BlockBehaviour.Properties builder, final AABB[] unrotatedAABBs) {
{ super(config, builder, unrotatedAABBs); } super(config, builder, unrotatedAABBs);
}
@Override @Override
public boolean isBlockEntityTicking(Level world, BlockState state) public boolean isBlockEntityTicking(Level world, BlockState state) {
{ return true; } return true;
}
@Override @Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
{ super.createBlockStateDefinition(builder); builder.add(ACTIVE); } super.createBlockStateDefinition(builder);
builder.add(ACTIVE);
}
@Override @Override
@Nullable @Nullable
public BlockState getStateForPlacement(BlockPlaceContext context) public BlockState getStateForPlacement(BlockPlaceContext context) {
{ return super.getStateForPlacement(context).setValue(ACTIVE, false); } return super.getStateForPlacement(context).setValue(ACTIVE, false);
}
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
@SuppressWarnings("deprecation") @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; if ((state.getBlock() != this) || (!state.getValue(ACTIVE))) return;
// Sound // Sound
{ {
@ -140,8 +137,7 @@ public class EdBreaker
@Override @Override
@SuppressWarnings("deprecation") @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; if (!(world instanceof Level) || (world.isClientSide)) return;
BlockEntity te = world.getBlockEntity(pos); BlockEntity te = world.getBlockEntity(pos);
if (!(te instanceof BreakerTileEntity)) return; if (!(te instanceof BreakerTileEntity)) return;
@ -150,23 +146,25 @@ public class EdBreaker
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public boolean isSignalSource(BlockState state) public boolean isSignalSource(BlockState state) {
{ return true; } return true;
}
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public int getSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side) public int getSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side) {
{ return 0; } return 0;
}
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public int getDirectSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side) public int getDirectSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side) {
{ return 0; } return 0;
}
@Override @Override
@SuppressWarnings("deprecation") @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; if (world.isClientSide()) return InteractionResult.SUCCESS;
BlockEntity te = world.getBlockEntity(pos); BlockEntity te = world.getBlockEntity(pos);
if (te instanceof BreakerTileEntity) ((BreakerTileEntity) te).state_message(player); if (te instanceof BreakerTileEntity) ((BreakerTileEntity) te).state_message(player);
@ -178,67 +176,11 @@ public class EdBreaker
// Tile entity // 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 IDLE_TICK_INTERVAL = 40;
public static final int TICK_INTERVAL = 5; 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<>(); private static final HashSet<Block> blacklist = new HashSet<>();
static { static {
blacklist.add(Blocks.AIR); blacklist.add(Blocks.AIR);
blacklist.add(Blocks.BEDROCK); blacklist.add(Blocks.BEDROCK);
@ -250,18 +192,29 @@ public class EdBreaker
blacklist.add(Blocks.BARRIER); 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(); final Block block = state.getBlock();
if (blacklist.contains(block)) return false; if (blacklist.contains(block)) return false;
if (state.isAir()) 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); float bh = state.getDestroySpeed(world, pos);
return !((bh < 0) || (bh > 55)); return !((bh < 0) || (bh > 55));
} }
private static void spawnBlockAsEntity(Level world, BlockPos pos, ItemStack stack) { 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, ItemEntity e = new ItemEntity(world,
((world.random.nextFloat() * 0.1) + 0.5) + pos.getX(), ((world.random.nextFloat() * 0.1) + 0.5) + pos.getX(),
((world.random.nextFloat() * 0.1) + 0.5) + pos.getY(), ((world.random.nextFloat() * 0.1) + 0.5) + pos.getY(),
@ -273,17 +226,66 @@ public class EdBreaker
world.addFreshEntity(e); 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 // 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. // tag spamming the game. So for now only FH and VH.
final BlockState state = world.getBlockState(pos); final BlockState state = world.getBlockState(pos);
return (state.getBlock() == ModContent.getBlock("factory_hopper")) || (state.getBlock() == Blocks.HOPPER); return (state.getBlock() == ModContent.getBlock("factory_hopper")) || (state.getBlock() == Blocks.HOPPER);
} }
private boolean breakBlock(BlockState state, BlockPos pos, Level world) public void block_updated() {
{ if (tick_timer_ > 2) tick_timer_ = 2;
if(world.isClientSide || (!(world instanceof ServerLevel)) || world.restoringBlockSnapshots) return false; // retry next cycle }
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; List<ItemStack> drops;
final Block block = state.getBlock(); final Block block = state.getBlock();
final boolean insert = canInsertInto(world, getBlockPos().below()); final boolean insert = canInsertInto(world, getBlockPos().below());
@ -298,14 +300,14 @@ public class EdBreaker
} }
} }
SoundType stype = state.getBlock().getSoundType(state, world, pos, null); 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; return true;
} }
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public void tick() public void tick() {
{
if (--tick_timer_ > 0) return; if (--tick_timer_ > 0) return;
tick_timer_ = TICK_INTERVAL; tick_timer_ = TICK_INTERVAL;
final BlockState device_state = level.getBlockState(worldPosition); 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 BlockPos target_pos = worldPosition.relative(device_state.getValue(BreakerBlock.HORIZONTAL_FACING));
final BlockState target_state = level.getBlockState(target_pos); final BlockState target_state = level.getBlockState(target_pos);
if ((level.hasNeighborSignal(worldPosition)) || (!isBreakable(target_state, target_pos, level))) { 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; proc_time_elapsed_ = 0;
tick_timer_ = IDLE_TICK_INTERVAL; tick_timer_ = IDLE_TICK_INTERVAL;
return; return;

View file

@ -8,6 +8,8 @@
*/ */
package dev.zontreck.engineerdecor.blocks; 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.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.sounds.SoundEvents; 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.AABB;
import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import dev.zontreck.engineerdecor.libmc.StandardBlocks;
import dev.zontreck.engineerdecor.libmc.Inventories;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
@ -41,25 +41,17 @@ import java.util.Collections;
import java.util.List; import java.util.List;
public class EdCatwalkBlock extends StandardBlocks.HorizontalFourWayWaterLoggable public class EdCatwalkBlock extends StandardBlocks.HorizontalFourWayWaterLoggable {
{
final Block railing_block; final Block railing_block;
final AABB base_aabb; final AABB base_aabb;
public EdCatwalkBlock(long config, BlockBehaviour.Properties properties, final AABB base_aabb, final AABB railing_aabb, final Block railing_block) 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; } super(config, properties, base_aabb, railing_aabb, 0);
this.railing_block = railing_block;
this.base_aabb = base_aabb;
}
@Override public static boolean place_consume(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, int shrink) {
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)
{
if (!world.setBlock(pos, state, Block.UPDATE_ALL)) return false; if (!world.setBlock(pos, state, Block.UPDATE_ALL)) return false;
world.playSound(player, pos, SoundEvents.METAL_PLACE, SoundSource.BLOCKS, 1f, 1f); world.playSound(player, pos, SoundEvents.METAL_PLACE, SoundSource.BLOCKS, 1f, 1f);
if ((!player.isCreative()) && (!world.isClientSide())) { if ((!player.isCreative()) && (!world.isClientSide())) {
@ -76,15 +68,26 @@ public class EdCatwalkBlock extends StandardBlocks.HorizontalFourWayWaterLoggabl
return true; 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 @Override
@SuppressWarnings("deprecation") @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(); final Item item = player.getItemInHand(hand).getItem();
if ((!(item instanceof BlockItem))) return InteractionResult.PASS; if ((!(item instanceof BlockItem))) return InteractionResult.PASS;
final Block block = ((BlockItem) item).getBlock(); final Block block = ((BlockItem) item).getBlock();
if (block == this) { 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()); BlockPos adjacent_pos = pos.relative(player.getDirection());
BlockState adjacent_state = world.getBlockState(adjacent_pos); BlockState adjacent_state = world.getBlockState(adjacent_pos);
if (adjacent_state.canBeReplaced(new DirectionalPlaceContext(world, adjacent_pos, hit.getDirection().getOpposite(), player.getItemInHand(hand), hit.getDirection()))) { 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())); final Vec3 rhv = hit.getLocation().subtract(Vec3.atCenterOf(hit.getBlockPos()));
if (face.getAxis().isHorizontal()) { if (face.getAxis().isHorizontal()) {
// Side or railing clicked // 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) { } else if (player.distanceToSqr(Vec3.atCenterOf(pos)) < 3) {
// near accurate placement // near accurate placement
face = Direction.getNearest(rhv.x, 0, rhv.z); face = Direction.getNearest(rhv.x, 0, rhv.z);
@ -119,12 +123,12 @@ public class EdCatwalkBlock extends StandardBlocks.HorizontalFourWayWaterLoggabl
} }
@Override @Override
public boolean hasDynamicDropList() public boolean hasDynamicDropList() {
{ return true; } return true;
}
@Override @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); if (world.isClientSide()) return Collections.singletonList(ItemStack.EMPTY);
List<ItemStack> drops = new ArrayList<>(); List<ItemStack> drops = new ArrayList<>();
drops.add(new ItemStack(state.getBlock().asItem())); drops.add(new ItemStack(state.getBlock().asItem()));

View file

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

View file

@ -8,6 +8,8 @@
*/ */
package dev.zontreck.engineerdecor.blocks; 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.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.world.InteractionHand; 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.CollisionContext;
import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape; import net.minecraft.world.phys.shapes.VoxelShape;
import dev.zontreck.engineerdecor.ModContent;
import dev.zontreck.engineerdecor.libmc.StandardBlocks;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
@ -42,14 +42,12 @@ import java.util.List;
import java.util.stream.Collectors; 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); public static final IntegerProperty VARIANT = IntegerProperty.create("variant", 0, 4);
protected final List<VoxelShape> variant_shapes; protected final List<VoxelShape> variant_shapes;
protected final Block inset_light_block; 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]); super(config, properties, variant_shapes[0]);
registerDefaultState(super.defaultBlockState().setValue(VARIANT, 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()); 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 @Override
public boolean propagatesSkylightDown(BlockState state, BlockGetter reader, BlockPos pos) public boolean propagatesSkylightDown(BlockState state, BlockGetter reader, BlockPos pos) {
{ return true; } return true;
}
@Override @Override
public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) {
{ return variant_shapes.get(state.getValue(VARIANT)); } return variant_shapes.get(state.getValue(VARIANT));
}
@Override @Override
public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) {
{ return getShape(state, world, pos, selectionContext); } return getShape(state, world, pos, selectionContext);
}
@Override @Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
{ super.createBlockStateDefinition(builder); builder.add(VARIANT); } super.createBlockStateDefinition(builder);
builder.add(VARIANT);
}
@Override @Override
@Nullable @Nullable
public BlockState getStateForPlacement(BlockPlaceContext context) public BlockState getStateForPlacement(BlockPlaceContext context) {
{
BlockState state = adapted_state(super.getStateForPlacement(context), context.getLevel(), context.getClickedPos()); BlockState state = adapted_state(super.getStateForPlacement(context), context.getLevel(), context.getClickedPos());
if (context.getClickedFace() != Direction.UP) return state; if (context.getClickedFace() != Direction.UP) return state;
BlockState below = context.getLevel().getBlockState(context.getClickedPos().below()); 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; return state;
} }
@Override @Override
@SuppressWarnings("deprecation") @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(); final Item item = player.getItemInHand(hand).getItem();
if ((!(item instanceof BlockItem))) return InteractionResult.PASS; if ((!(item instanceof BlockItem))) return InteractionResult.PASS;
final Block block = ((BlockItem) item).getBlock(); final Block block = ((BlockItem) item).getBlock();
@ -112,17 +114,19 @@ public class EdCatwalkTopAlignedBlock extends StandardBlocks.WaterLoggable
} }
@Override @Override
public BlockState updateShape(BlockState state, Direction facing, BlockState facingState, LevelAccessor world, BlockPos pos, BlockPos facingPos) 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); } 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()); BlockState below = world.getBlockState(pos.below());
if (state == null || state.getValue(VARIANT) == 4) return state; 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("thick_steel_pole")) || (below.getBlock() == ModContent.getBlock("thick_steel_pole_head")))
if((below.getBlock() == ModContent.getBlock("thin_steel_pole")) || (below.getBlock() == ModContent.getBlock("thin_steel_pole_head"))) return state.setValue(VARIANT, 2); 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; return state;
} }
@ -134,12 +138,12 @@ public class EdCatwalkTopAlignedBlock extends StandardBlocks.WaterLoggable
} }
@Override @Override
public boolean hasDynamicDropList() public boolean hasDynamicDropList() {
{ return true; } return true;
}
@Override @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); if (world.isClientSide()) return Collections.singletonList(ItemStack.EMPTY);
List<ItemStack> drops = new ArrayList<>(); List<ItemStack> drops = new ArrayList<>();
drops.add(new ItemStack(state.getBlock().asItem())); drops.add(new ItemStack(state.getBlock().asItem()));

View file

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

View file

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

View file

@ -19,18 +19,18 @@ import net.minecraft.world.phys.shapes.VoxelShape;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public class EdChimneyTrunkBlock extends EdRoofBlock public class EdChimneyTrunkBlock extends EdRoofBlock {
{ public EdChimneyTrunkBlock(long config, BlockBehaviour.Properties properties) {
public EdChimneyTrunkBlock(long config, BlockBehaviour.Properties properties) super(config, properties.dynamicShape(), Shapes.empty(), Shapes.empty());
{ super(config, properties.dynamicShape(), Shapes.empty(), Shapes.empty()); } }
public EdChimneyTrunkBlock(long config, BlockBehaviour.Properties properties, VoxelShape add, VoxelShape cut) public EdChimneyTrunkBlock(long config, BlockBehaviour.Properties properties, VoxelShape add, VoxelShape cut) {
{ super(config, properties, add, cut); } super(config, properties, add, cut);
}
@Override @Override
@Nullable @Nullable
public BlockState getStateForPlacement(BlockPlaceContext context) public BlockState getStateForPlacement(BlockPlaceContext context) {
{
BlockState state = super.getStateForPlacement(context); BlockState state = super.getStateForPlacement(context);
return (state == null) ? (state) : (state.setValue(EdRoofBlock.SHAPE, StairsShape.STRAIGHT).setValue(EdRoofBlock.HALF, Half.BOTTOM)); 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; 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.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.util.Mth; 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.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec2; import net.minecraft.world.phys.Vec2;
import dev.zontreck.engineerdecor.libmc.StandardBlocks;
import dev.zontreck.engineerdecor.libmc.Auxiliaries;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
public class EdCornerOrnamentedBlock extends StandardBlocks.Directed public class EdCornerOrnamentedBlock extends StandardBlocks.Directed {
{
protected final HashSet<Block> compatible_blocks; 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)); super(config, properties, Auxiliaries.getPixeledAABB(0, 0, 0, 16, 16, 16));
compatible_blocks = new HashSet<>(Arrays.asList(assigned_wall_blocks)); compatible_blocks = new HashSet<>(Arrays.asList(assigned_wall_blocks));
} }
@Override @Override
@Nullable @Nullable
public BlockState getStateForPlacement(BlockPlaceContext context) public BlockState getStateForPlacement(BlockPlaceContext context) {
{
final Level world = context.getLevel(); final Level world = context.getLevel();
final BlockPos pos = context.getClickedPos(); final BlockPos pos = context.getClickedPos();
// 1. Placement as below/above for corners, or placement adjacent horizontally if up/down facing. // 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; 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.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.sounds.SoundEvents; 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.CollisionContext;
import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape; import net.minecraft.world.phys.shapes.VoxelShape;
import dev.zontreck.engineerdecor.libmc.StandardBlocks;
import dev.zontreck.engineerdecor.libmc.Auxiliaries;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; 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 IntegerProperty SEGMENT = IntegerProperty.create("segment", 0, 1);
public static final BooleanProperty OPEN = FenceGateBlock.OPEN; public static final BooleanProperty OPEN = FenceGateBlock.OPEN;
public static final int SEGMENT_LOWER = 0; public static final int SEGMENT_LOWER = 0;
public static final int SEGMENT_UPPER = 1; public static final int SEGMENT_UPPER = 1;
protected final ArrayList<VoxelShape> collision_shapes_; protected final ArrayList<VoxelShape> collision_shapes_;
public EdDoubleGateBlock(long config, BlockBehaviour.Properties properties, AABB aabb) public EdDoubleGateBlock(long config, BlockBehaviour.Properties properties, AABB aabb) {
{ this(config, properties, new 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); super(config, properties, aabbs);
AABB[] caabbs = new AABB[aabbs.length]; AABB[] caabbs = new AABB[aabbs.length];
for (int i = 0; i < caabbs.length; ++i) caabbs[i] = aabbs[i].expandTowards(0, 0.5, 0); 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 @Override
public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) 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); } return state.getValue(OPEN) ? Shapes.empty() : collision_shapes_.get(state.getValue(HORIZONTAL_FACING).get3DDataValue() & 0x7);
}
@Override @Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
{ super.createBlockStateDefinition(builder); builder.add(SEGMENT).add(OPEN); } super.createBlockStateDefinition(builder);
builder.add(SEGMENT).add(OPEN);
}
@Override @Override
@Nullable @Nullable
public BlockState getStateForPlacement(BlockPlaceContext context) public BlockState getStateForPlacement(BlockPlaceContext context) {
{ return getInitialState(super.getStateForPlacement(context), context.getLevel(), context.getClickedPos()); } return getInitialState(super.getStateForPlacement(context), context.getLevel(), context.getClickedPos());
}
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public BlockState updateShape(BlockState state, Direction facing, BlockState facingState, LevelAccessor world, BlockPos pos, BlockPos facingPos) 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); } return getInitialState(super.updateShape(state, facing, facingState, world, pos, facingPos), world, pos);
}
@Override @Override
@SuppressWarnings("deprecation") @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 ((rayTraceResult.getDirection() == Direction.UP) || (rayTraceResult.getDirection() == Direction.DOWN) && (player.getItemInHand(hand).getItem() == this.asItem()))
if((rayTraceResult.getDirection()==Direction.UP) || (rayTraceResult.getDirection()==Direction.DOWN) && (player.getItemInHand(hand).getItem()==this.asItem())) return InteractionResult.PASS; return InteractionResult.PASS;
if (world.isClientSide()) return InteractionResult.SUCCESS; if (world.isClientSide()) return InteractionResult.SUCCESS;
final boolean open = !state.getValue(OPEN); final boolean open = !state.getValue(OPEN);
world.setBlock(pos, state.setValue(OPEN, open), 2 | 8 | 16); world.setBlock(pos, state.setValue(OPEN, open), 2 | 8 | 16);
@ -107,13 +111,13 @@ public class EdDoubleGateBlock extends StandardBlocks.HorizontalWaterLoggable
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public boolean isPathfindable(BlockState state, BlockGetter world, BlockPos pos, PathComputationType type) public boolean isPathfindable(BlockState state, BlockGetter world, BlockPos pos, PathComputationType type) {
{ return state.getValue(OPEN); } return state.getValue(OPEN);
}
@Override @Override
@SuppressWarnings("deprecation") @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; if (world.isClientSide) return;
boolean powered = false; boolean powered = false;
BlockState adjacent; 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()); 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()); 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); return state.setValue(SEGMENT, SEGMENT_LOWER).setValue(OPEN, false);
} }

View file

@ -8,9 +8,10 @@
*/ */
package dev.zontreck.engineerdecor.blocks; package dev.zontreck.engineerdecor.blocks;
import com.mojang.blaze3d.vertex.PoseStack; import dev.zontreck.engineerdecor.ModConfig;
import dev.zontreck.engineerdecor.libmc.Networking; import dev.zontreck.engineerdecor.ModContent;
import dev.zontreck.engineerdecor.libmc.TooltipDisplay; import dev.zontreck.libzontreck.edlibmc.*;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag; 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.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level; 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.Block;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockBehaviour; 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.capabilities.ForgeCapabilities;
import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.items.IItemHandler; 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 javax.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
@ -66,12 +57,10 @@ import java.util.Collections;
import java.util.List; import java.util.List;
public class EdDropper public class EdDropper {
{
private static boolean with_adjacent_item_insertion = false; 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; with_adjacent_item_insertion = with_item_insertion;
ModConfig.log("Config dropper: item-insertion:" + with_adjacent_item_insertion + "."); ModConfig.log("Config dropper: item-insertion:" + with_adjacent_item_insertion + ".");
} }
@ -80,47 +69,54 @@ public class EdDropper
// Block // 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 static final BooleanProperty OPEN = BlockStateProperties.OPEN;
public DropperBlock(long config, BlockBehaviour.Properties builder, final AABB unrotatedAABB) public DropperBlock(long config, BlockBehaviour.Properties builder, final AABB unrotatedAABB) {
{ super(config, builder, unrotatedAABB); } super(config, builder, unrotatedAABB);
}
@Override @Override
public boolean isBlockEntityTicking(Level world, BlockState state) public boolean isBlockEntityTicking(Level world, BlockState state) {
{ return true; } return true;
}
@Override @Override
public RenderTypeHint getRenderTypeHint() public RenderTypeHint getRenderTypeHint() {
{ return RenderTypeHint.SOLID; } return RenderTypeHint.SOLID;
}
@Override @Override
public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) {
{ return Shapes.block(); } return Shapes.block();
}
@Override @Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
{ super.createBlockStateDefinition(builder); builder.add(OPEN); } super.createBlockStateDefinition(builder);
builder.add(OPEN);
}
@Override @Override
@Nullable @Nullable
public BlockState getStateForPlacement(BlockPlaceContext context) public BlockState getStateForPlacement(BlockPlaceContext context) {
{ return super.getStateForPlacement(context).setValue(OPEN, false); } return super.getStateForPlacement(context).setValue(OPEN, false);
}
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public boolean hasAnalogOutputSignal(BlockState state) public boolean hasAnalogOutputSignal(BlockState state) {
{ return true; } return true;
}
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public int getAnalogOutputSignal(BlockState blockState, Level world, BlockPos pos) public int getAnalogOutputSignal(BlockState blockState, Level world, BlockPos pos) {
{ return (world.getBlockEntity(pos) instanceof DropperTileEntity te) ? RsSignals.fromContainer(te.storage_slot_range_) : 0; } return (world.getBlockEntity(pos) instanceof DropperTileEntity te) ? RsSignals.fromContainer(te.storage_slot_range_) : 0;
}
@Override @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 (world.isClientSide) return;
if ((!stack.hasTag()) || (!stack.getTag().contains("tedata"))) return; if ((!stack.hasTag()) || (!stack.getTag().contains("tedata"))) return;
CompoundTag te_nbt = stack.getTag().getCompound("tedata"); CompoundTag te_nbt = stack.getTag().getCompound("tedata");
@ -133,12 +129,12 @@ public class EdDropper
} }
@Override @Override
public boolean hasDynamicDropList() public boolean hasDynamicDropList() {
{ return true; } return true;
}
@Override @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<>(); final List<ItemStack> stacks = new ArrayList<>();
if (world.isClientSide) return stacks; if (world.isClientSide) return stacks;
if (!(te instanceof DropperTileEntity)) return stacks; if (!(te instanceof DropperTileEntity)) return stacks;
@ -162,13 +158,13 @@ public class EdDropper
@Override @Override
@SuppressWarnings("deprecation") @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) {
{ return useOpenGui(state, world, pos, player); } return useOpenGui(state, world, pos, player);
}
@Override @Override
@SuppressWarnings("deprecation") @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; if (!(world instanceof Level) || (world.isClientSide)) return;
BlockEntity te = world.getBlockEntity(pos); BlockEntity te = world.getBlockEntity(pos);
if (!(te instanceof DropperTileEntity)) return; if (!(te instanceof DropperTileEntity)) return;
@ -176,16 +172,16 @@ public class EdDropper
} }
@Override @Override
public boolean shouldCheckWeakPower(BlockState state, LevelReader world, BlockPos pos, Direction side) public boolean shouldCheckWeakPower(BlockState state, SignalGetter level, BlockPos pos, Direction side) {
{ return false; } return false;
}
} }
//-------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------
// Tile entity // 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 NUM_OF_FIELDS = 16;
public static final int TICK_INTERVAL = 32; public static final int TICK_INTERVAL = 32;
public static final int NUM_OF_SLOTS = 15; 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_SILENT_OPEN = 0x08;
public static final int DROPLOGIC_CONTINUOUS = 0x10; public static final int DROPLOGIC_CONTINUOUS = 0x10;
public static final int DROPLOGIC_IGNORE_EXT = 0x20; 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 final int[] filter_matches_ = new int[CTRL_SLOTS_SIZE];
private int open_timer_ = 0; private int open_timer_ = 0;
@ -218,124 +218,14 @@ public class EdDropper
private int drop_logic_ = DROPLOGIC_EXTERN_ANDGATE; private int drop_logic_ = DROPLOGIC_EXTERN_ANDGATE;
private int drop_period_ = 0; private int drop_period_ = 0;
private int drop_slot_index_ = 0; private int drop_slot_index_ = 0;
private int tick_timer_ = 0; protected final ContainerData fields = new ContainerData() {
protected final Inventories.StorageInventory main_inventory_ = new StorageInventory(this, NUM_OF_SLOTS, 1); @Override
protected final InventoryRange storage_slot_range_ = new InventoryRange(main_inventory_, INPUT_SLOTS_FIRST, INPUT_SLOTS_SIZE); public int getCount() {
protected final InventoryRange filter_slot_range_ = new InventoryRange(main_inventory_, CTRL_SLOTS_FIRST, CTRL_SLOTS_SIZE); return DropperTileEntity.NUM_OF_FIELDS;
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;
} }
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 @Override
public void load(CompoundTag nbt) public int get(int id) {
{ 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)
{
return switch (id) { return switch (id) {
case 0 -> drop_speed_; case 0 -> drop_speed_;
case 1 -> drop_xdev_; case 1 -> drop_xdev_;
@ -354,9 +244,9 @@ public class EdDropper
default -> 0; default -> 0;
}; };
} }
@Override @Override
public void set(int id, int value) public void set(int id, int value) {
{
switch (id) { switch (id) {
case 0 -> drop_speed_ = Mth.clamp(value, 0, 100); case 0 -> drop_speed_ = Mth.clamp(value, 0, 100);
case 1 -> drop_xdev_ = Mth.clamp(value, -100, 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 12 -> filter_matches_[0] = (value & 0x3);
case 13 -> filter_matches_[1] = (value & 0x3); case 13 -> filter_matches_[1] = (value & 0x3);
case 14 -> filter_matches_[2] = (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 ------------------------------------------------------------------------------------ public DropperTileEntity(BlockPos pos, BlockState state) {
super(ModContent.getBlockEntityTypeOfBlock(state.getBlock()), pos, state);
@Override reset_rtstate();
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);
} }
// 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; final double ofs = facing == Direction.DOWN ? 0.8 : 0.7;
Vec3 v0 = new Vec3(facing.getStepX(), facing.getStepY(), facing.getStepZ()); 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); 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); 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 (Arrays.stream(stacks).allMatch(ItemStack::isEmpty)) return new Tuple<>(false, Arrays.asList(stacks));
if (with_adjacent_item_insertion) { if (with_adjacent_item_insertion) {
final BlockEntity te = world.getBlockEntity(pos.relative(facing)); final BlockEntity te = world.getBlockEntity(pos.relative(facing));
@ -446,9 +330,125 @@ public class EdDropper
return new Tuple<>(true, Collections.emptyList()); 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 @Nullable
BlockState update_blockstate() BlockState update_blockstate() {
{
BlockState state = level.getBlockState(worldPosition); BlockState state = level.getBlockState(worldPosition);
if (!(state.getBlock() instanceof DropperBlock)) return null; if (!(state.getBlock() instanceof DropperBlock)) return null;
boolean open = (open_timer_ > 0); boolean open = (open_timer_ > 0);
@ -466,12 +466,8 @@ public class EdDropper
return state; return state;
} }
private static int next_slot(int i)
{ return (i<INPUT_SLOTS_SIZE-1) ? (i+1) : INPUT_SLOTS_FIRST; }
@Override @Override
public void tick() public void tick() {
{
if (level.isClientSide) return; if (level.isClientSide) return;
if (--open_timer_ < 0) open_timer_ = 0; if (--open_timer_ < 0) open_timer_ = 0;
if ((drop_timer_ > 0) && ((--drop_timer_) == 0)) setChanged(); if ((drop_timer_ > 0) && ((--drop_timer_) == 0)) setChanged();
@ -500,9 +496,15 @@ public class EdDropper
int inventory_item_count = 0; int inventory_item_count = 0;
int slot = drop_slot_index_; int slot = drop_slot_index_;
for (final ItemStack inp_stack : storage_slot_range_) { 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(); 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; filter_matches_[ci] = 2;
break; break;
} }
@ -515,7 +517,8 @@ public class EdDropper
} }
filter_defined = (filter_nset > 0); filter_defined = (filter_nset > 0);
filter_trigger = ((filter_nset > 0) && (nmatched > 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 // gates
{ {
@ -524,7 +527,10 @@ public class EdDropper
} else { } else {
trigger = redstone_trigger; 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 (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. if (open_timer_ > 10) open_timer_ = 10; // override if dropping is not possible at all.
} else if (trigger || filter_trigger || redstone_trigger) { } else if (trigger || filter_trigger || redstone_trigger) {
@ -541,7 +547,10 @@ public class EdDropper
} }
// block state update // block state update
final BlockState state = update_blockstate(); final BlockState state = update_blockstate();
if(state == null) { block_power_signal_= false; return; } if (state == null) {
block_power_signal_ = false;
return;
}
// dispense action // dispense action
if (trigger && (drop_timer_ <= 0)) { if (trigger && (drop_timer_ <= 0)) {
// drop stack for non-filter triggers // drop stack for non-filter triggers
@ -593,7 +602,8 @@ public class EdDropper
final boolean dropped = res.getA(); final boolean dropped = res.getA();
final List<ItemStack> remaining = res.getB(); final List<ItemStack> remaining = res.getB();
for (ItemStack st : remaining) { 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; if (dropped || (!remaining.isEmpty())) dirty = true;
// cooldown // cooldown
@ -607,7 +617,10 @@ public class EdDropper
{ {
boolean found = false; boolean found = false;
for (int i = 0; i < storage_slot_range_.size(); ++i) { 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_); drop_slot_index_ = next_slot(drop_slot_index_);
} }
if (!found) drop_slot_index_ = 0; if (!found) drop_slot_index_ = 0;
@ -622,31 +635,28 @@ public class EdDropper
// Container // 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"; protected static final String QUICK_MOVE_ALL = "quick-move-all";
private static final int PLAYER_INV_START_SLOTNO = DropperTileEntity.NUM_OF_SLOTS; private static final int PLAYER_INV_START_SLOTNO = DropperTileEntity.NUM_OF_SLOTS;
private final Player player_; private final Player player_;
private final Container inventory_; private final Container inventory_;
private final ContainerLevelAccess wpc_; private final ContainerLevelAccess wpc_;
private final ContainerData fields_; private final ContainerData fields_;
private final InventoryRange player_inventory_range_; private final Inventories.InventoryRange player_inventory_range_;
private final InventoryRange block_storage_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) private DropperUiContainer(int cid, Inventory player_inventory, Container block_inventory, ContainerLevelAccess wpc, ContainerData fields) {
{ 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)
{
super(ModContent.getMenuType("factory_dropper"), cid); // @todo: class mapping super(ModContent.getMenuType("factory_dropper"), cid); // @todo: class mapping
fields_ = fields; fields_ = fields;
wpc_ = wpc; wpc_ = wpc;
player_ = player_inventory.player; player_ = player_inventory.player;
inventory_ = block_inventory; inventory_ = block_inventory;
block_storage_range_ = new InventoryRange(inventory_, 0, DropperTileEntity.NUM_OF_SLOTS); block_storage_range_ = new Inventories.InventoryRange(inventory_, 0, DropperTileEntity.NUM_OF_SLOTS);
player_inventory_range_ = InventoryRange.fromPlayerInventory(player_); player_inventory_range_ = Inventories.InventoryRange.fromPlayerInventory(player_);
int i = -1; int i = -1;
// input slots (stacks 0 to 11) // input slots (stacks 0 to 11)
for (int y = 0; y < 2; ++y) { for (int y = 0; y < 2; ++y) {
@ -671,20 +681,25 @@ public class EdDropper
this.addDataSlots(fields_); // === Add reference holders this.addDataSlots(fields_); // === Add reference holders
} }
@Override public final int field(int index) {
public boolean stillValid(Player player) return fields_.get(index);
{ return inventory_.stillValid(player); } }
@Override @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); Slot slot = getSlot(index);
if ((slot == null) || (!slot.hasItem())) return ItemStack.EMPTY; if ((slot == null) || (!slot.hasItem())) return ItemStack.EMPTY;
ItemStack slot_stack = slot.getItem(); ItemStack slot_stack = slot.getItem();
ItemStack transferred = slot_stack.copy(); ItemStack transferred = slot_stack.copy();
if ((index >= 0) && (index < PLAYER_INV_START_SLOTNO)) { if ((index >= 0) && (index < PLAYER_INV_START_SLOTNO)) {
// Device slots // 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)) { } else if ((index >= PLAYER_INV_START_SLOTNO) && (index <= PLAYER_INV_START_SLOTNO + 36)) {
// Player slot // Player slot
if (!moveItemStackTo(slot_stack, 0, DropperTileEntity.INPUT_SLOTS_SIZE, false)) return ItemStack.EMPTY; if (!moveItemStackTo(slot_stack, 0, DropperTileEntity.INPUT_SLOTS_SIZE, false)) return ItemStack.EMPTY;
@ -705,33 +720,32 @@ public class EdDropper
// INetworkSynchronisableContainer --------------------------------------------------------- // INetworkSynchronisableContainer ---------------------------------------------------------
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public void onGuiAction(CompoundTag nbt) public void onGuiAction(CompoundTag nbt) {
{ Networking.PacketContainerSyncClientToServer.sendToServer(containerId, nbt); } Networking.PacketContainerSyncClientToServer.sendToServer(containerId, nbt);
}
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public void onGuiAction(String key, int value) public void onGuiAction(String key, int value) {
{
CompoundTag nbt = new CompoundTag(); CompoundTag nbt = new CompoundTag();
nbt.putInt(key, value); nbt.putInt(key, value);
Networking.PacketContainerSyncClientToServer.sendToServer(containerId, nbt); Networking.PacketContainerSyncClientToServer.sendToServer(containerId, nbt);
} }
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public void onGuiAction(String message, CompoundTag nbt) public void onGuiAction(String message, CompoundTag nbt) {
{
nbt.putString("action", message); nbt.putString("action", message);
Networking.PacketContainerSyncClientToServer.sendToServer(containerId, nbt); Networking.PacketContainerSyncClientToServer.sendToServer(containerId, nbt);
} }
@Override @Override
public void onServerPacketReceived(int windowId, CompoundTag nbt) public void onServerPacketReceived(int windowId, CompoundTag nbt) {
{} }
@Override @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 (!(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")) { if (nbt.contains("action")) {
boolean changed = false; boolean changed = false;
final int slotId = nbt.contains("slot") ? nbt.getInt("slot") : -1; 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_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_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_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_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("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_rstrigger") && (nbt.getInt("manual_rstrigger") != 0)) {
if(nbt.contains("manual_trigger") && (nbt.getInt("manual_trigger")!=0)) { te.tick_timer_ = 1; te.triggered_ = true; } 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(); te.setChanged();
} }
} }
@ -769,14 +791,13 @@ public class EdDropper
//-------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public static class DropperGui extends Guis.ContainerGui<DropperUiContainer> public static class DropperGui extends Guis.ContainerGui<DropperUiContainer> {
{ public DropperGui(DropperUiContainer container, Inventory player_inventory, Component title) {
public DropperGui(DropperUiContainer container, Inventory player_inventory, Component title) super(container, player_inventory, title, "textures/gui/factory_dropper_gui.png");
{ super(container, player_inventory, title, "textures/gui/factory_dropper_gui.png"); } }
@Override @Override
public void init() public void init() {
{
super.init(); super.init();
{ {
final Block block = ModContent.getBlock(Auxiliaries.getResourceLocation(getMenu().getType()).getPath().replaceAll("^ct_", "")); final Block block = ModContent.getBlock(Auxiliaries.getResourceLocation(getMenu().getType()).getPath().replaceAll("^ct_", ""));
@ -796,8 +817,7 @@ public class EdDropper
} }
@Override @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(); final int x0 = getGuiLeft(), y0 = getGuiTop(), w = getXSize(), h = getYSize();
DropperUiContainer container = getMenu(); DropperUiContainer container = getMenu();
// active drop slot // active drop slot
@ -806,14 +826,14 @@ public class EdDropper
if ((drop_slot_index < 0) || (drop_slot_index >= 16)) drop_slot_index = 0; if ((drop_slot_index < 0) || (drop_slot_index >= 16)) drop_slot_index = 0;
int x = (x0 + 9 + ((drop_slot_index % 6) * 18)); int x = (x0 + 9 + ((drop_slot_index % 6) * 18));
int y = (y0 + 5 + ((drop_slot_index / 6) * 17)); 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 // filter LEDs
{ {
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
int xt = 180 + (6 * container.field(12 + i)), yt = 38; int xt = 180 + (6 * container.field(12 + i)), yt = 38;
int x = x0 + 31 + (i * 36), y = y0 + 65; 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 // force adjustment
@ -821,31 +841,31 @@ public class EdDropper
int hy = 2 + (((100 - container.field(0)) * 21) / 100); int hy = 2 + (((100 - container.field(0)) * 21) / 100);
int x = x0 + 135, y = y0 + 12, xt = 181; int x = x0 + 135, y = y0 + 12, xt = 181;
int yt = 4 + (23 - hy); int yt = 4 + (23 - hy);
blit(mx, x, y, xt, yt, 3, hy); mx.blit(getBackgroundImage(), x, y, xt, yt, 3, hy);
} }
// angle adjustment // angle adjustment
{ {
int x = x0 + 157 - 3 + ((container.field(1) * 12) / 100); int x = x0 + 157 - 3 + ((container.field(1) * 12) / 100);
int y = y0 + 22 - 3 - ((container.field(2) * 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 // drop count
{ {
int x = x0 + 134 - 2 + (container.field(4)); int x = x0 + 134 - 2 + (container.field(4));
int y = y0 + 45; int y = y0 + 45;
blit(mx, x, y, 190, 31, 5, 5); mx.blit(getBackgroundImage(), x, y, 190, 31, 5, 5);
} }
// drop period // drop period
{ {
int px = (int) Math.round(((33.0 * container.field(6)) / 100) + 1); int px = (int) Math.round(((33.0 * container.field(6)) / 100) + 1);
int x = x0 + 134 - 2 + Mth.clamp(px, 0, 33); int x = x0 + 134 - 2 + Mth.clamp(px, 0, 33);
int y = y0 + 56; int y = y0 + 56;
blit(mx, x, y, 190, 31, 5, 5); mx.blit(getBackgroundImage(), x, y, 190, 31, 5, 5);
} }
// redstone input // redstone input
{ {
if (container.field(11) != 0) { 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 // trigger logic
@ -855,21 +875,20 @@ public class EdDropper
int pulse_mode_offset = ((logic & DropperTileEntity.DROPLOGIC_CONTINUOUS) != 0) ? 10 : 0; 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_x = ((logic & DropperTileEntity.DROPLOGIC_EXTERN_ANDGATE) != 0) ? 11 : 0;
int extern_gate_offset_y = ((logic & DropperTileEntity.DROPLOGIC_IGNORE_EXT) != 0) ? 10 : 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); mx.blit(getBackgroundImage(), 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); mx.blit(getBackgroundImage(), 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 + 162, y0 + 66, 200 + pulse_mode_offset, 66, 9, 9);
} }
// drop timer running indicator // drop timer running indicator
{ {
if ((container.field(9) > DropperTileEntity.DROP_PERIOD_OFFSET) && ((System.currentTimeMillis() % 1000) < 500)) { 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 @Override
public boolean mouseClicked(double mouseX, double mouseY, int mouseButton) public boolean mouseClicked(double mouseX, double mouseY, int mouseButton) {
{
tooltip_.resetTimer(); tooltip_.resetTimer();
DropperUiContainer container = getMenu(); DropperUiContainer container = getMenu();
int mx = (int) (mouseX - getGuiLeft() + .5), my = (int) (mouseY - getGuiTop() + .5); int mx = (int) (mouseX - getGuiLeft() + .5), my = (int) (mouseY - getGuiTop() + .5);
@ -928,8 +947,7 @@ public class EdDropper
} }
@Override @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(); tooltip_.resetTimer();
if ((type == ClickType.QUICK_MOVE) && (slot != null) && slot.hasItem() && Auxiliaries.isShiftDown() && Auxiliaries.isCtrlDown()) { if ((type == ClickType.QUICK_MOVE) && (slot != null) && slot.hasItem() && Auxiliaries.isShiftDown() && Auxiliaries.isCtrlDown()) {
CompoundTag nbt = new CompoundTag(); CompoundTag nbt = new CompoundTag();

View file

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

View file

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

View file

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

View file

@ -10,6 +10,11 @@
*/ */
package dev.zontreck.engineerdecor.blocks; 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.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.core.Vec3i; 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.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level; 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.Block;
import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BlockEntity; 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.common.util.LazyOptional;
import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.IFluidHandler; 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 javax.annotation.Nullable;
import java.util.*; import java.util.*;
public class EdFluidFunnel public class EdFluidFunnel {
{
private static boolean with_device_fluid_handler_collection = false; 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; with_device_fluid_handler_collection = with_tank_fluid_collection;
ModConfig.log("Config fluid funnel: tank-fluid-collection:" + with_device_fluid_handler_collection + "."); ModConfig.log("Config fluid funnel: tank-fluid-collection:" + with_device_fluid_handler_collection + ".");
} }
@ -68,48 +66,55 @@ public class EdFluidFunnel
// Block // 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 int FILL_LEVEL_MAX = 3;
public static final IntegerProperty FILL_LEVEL = IntegerProperty.create("level", 0, FILL_LEVEL_MAX); public static final IntegerProperty FILL_LEVEL = IntegerProperty.create("level", 0, FILL_LEVEL_MAX);
public FluidFunnelBlock(long config, BlockBehaviour.Properties builder, final AABB[] unrotatedAABB) public FluidFunnelBlock(long config, BlockBehaviour.Properties builder, final AABB[] unrotatedAABB) {
{ super(config, builder, unrotatedAABB); } super(config, builder, unrotatedAABB);
}
@Override @Override
public boolean isBlockEntityTicking(Level world, BlockState state) public boolean isBlockEntityTicking(Level world, BlockState state) {
{ return true; } return true;
}
@Override @Override
public RenderTypeHint getRenderTypeHint() public RenderTypeHint getRenderTypeHint() {
{ return RenderTypeHint.CUTOUT; } return RenderTypeHint.CUTOUT;
}
@Override @Override
public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) {
{ return Shapes.block(); } return Shapes.block();
}
@Override @Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
{ super.createBlockStateDefinition(builder); builder.add(FILL_LEVEL); } super.createBlockStateDefinition(builder);
builder.add(FILL_LEVEL);
}
@Override @Override
@Nullable @Nullable
public BlockState getStateForPlacement(BlockPlaceContext context) public BlockState getStateForPlacement(BlockPlaceContext context) {
{ return super.getStateForPlacement(context).setValue(FILL_LEVEL, 0); } return super.getStateForPlacement(context).setValue(FILL_LEVEL, 0);
}
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public boolean hasAnalogOutputSignal(BlockState state) public boolean hasAnalogOutputSignal(BlockState state) {
{ return true; } return true;
}
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public int getAnalogOutputSignal(BlockState state, Level world, BlockPos pos) public int getAnalogOutputSignal(BlockState state, Level world, BlockPos pos) {
{ return Mth.clamp((state.getValue(FILL_LEVEL)*5), 0, 15); } return Mth.clamp((state.getValue(FILL_LEVEL) * 5), 0, 15);
}
@Override @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 (world.isClientSide) return;
if ((!stack.hasTag()) || (!stack.getTag().contains("tedata"))) return; if ((!stack.hasTag()) || (!stack.getTag().contains("tedata"))) return;
CompoundTag te_nbt = stack.getTag().getCompound("tedata"); CompoundTag te_nbt = stack.getTag().getCompound("tedata");
@ -122,12 +127,12 @@ public class EdFluidFunnel
} }
@Override @Override
public boolean hasDynamicDropList() public boolean hasDynamicDropList() {
{ return true; } return true;
}
@Override @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<>(); final List<ItemStack> stacks = new ArrayList<>();
if (world.isClientSide) return stacks; if (world.isClientSide) return stacks;
if (!(te instanceof FluidFunnelTileEntity)) return stacks; if (!(te instanceof FluidFunnelTileEntity)) return stacks;
@ -149,28 +154,30 @@ public class EdFluidFunnel
@Override @Override
@SuppressWarnings("deprecation") @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; if (world.isClientSide) return InteractionResult.SUCCESS;
return (world.getBlockEntity(pos) instanceof FluidFunnelTileEntity) && Fluidics.manualFluidHandlerInteraction(player, hand, world, pos, rayTraceResult.getDirection()) ? InteractionResult.CONSUME : InteractionResult.FAIL; return (world.getBlockEntity(pos) instanceof FluidFunnelTileEntity) && Fluidics.manualFluidHandlerInteraction(player, hand, world, pos, rayTraceResult.getDirection()) ? InteractionResult.CONSUME : InteractionResult.FAIL;
} }
@Override @Override
@SuppressWarnings("deprecation") @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) {
{ BlockEntity te = world.getBlockEntity(pos); if(te instanceof FluidFunnelTileEntity) ((FluidFunnelTileEntity)te).block_changed(); } BlockEntity te = world.getBlockEntity(pos);
if (te instanceof FluidFunnelTileEntity) ((FluidFunnelTileEntity) te).block_changed();
}
@Override @Override
public boolean shouldCheckWeakPower(BlockState state, LevelReader world, BlockPos pos, Direction side) public boolean shouldCheckWeakPower(BlockState state, SignalGetter level, BlockPos pos, Direction side) {
{ return false; } return false;
}
} }
//-------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------
// Tile entity // 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 TANK_CAPACITY = 3000;
public static final int TICK_INTERVAL = 10; // ca 500ms 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. 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_TRACKING_STEPS_PER_CYCLE_INTENSIVE = 1024;
public static final int MAX_TRACK_RADIUS_SQ = MAX_TRACK_RADIUS * MAX_TRACK_RADIUS; public static final int MAX_TRACK_RADIUS_SQ = MAX_TRACK_RADIUS * MAX_TRACK_RADIUS;
public static final int INTENSIVE_SEARCH_TRIGGER_THRESHOLD = 16; 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 tick_timer_ = 0;
private int collection_timer_ = 0; private int collection_timer_ = 0;
private int no_fluid_found_counter_ = 0; private int no_fluid_found_counter_ = 0;
@ -186,38 +195,39 @@ public class EdFluidFunnel
private int total_pick_counter_ = 0; private int total_pick_counter_ = 0;
private BlockPos last_pick_pos_ = BlockPos.ZERO; private BlockPos last_pick_pos_ = BlockPos.ZERO;
private ArrayList<Vec3i> search_offsets_ = null; 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) public FluidFunnelTileEntity(BlockPos pos, BlockState state) {
{ super(ModContent.getBlockEntityTypeOfBlock(state.getBlock()), pos, state); } super(ModContent.getBlockEntityTypeOfBlock(state.getBlock()), pos, state);
}
public void readnbt(CompoundTag nbt) public void readnbt(CompoundTag nbt) {
{
tank_.load(nbt); tank_.load(nbt);
} }
public void writenbt(CompoundTag nbt) public void writenbt(CompoundTag nbt) {
{
tank_.save(nbt); tank_.save(nbt);
} }
public void block_changed() public void block_changed() {
{ tick_timer_ = TICK_INTERVAL; } tick_timer_ = TICK_INTERVAL;
}
// BlockEntity ----------------------------------------------------------------------------------------- // BlockEntity -----------------------------------------------------------------------------------------
@Override @Override
public void load(CompoundTag nbt) public void load(CompoundTag nbt) {
{ super.load(nbt); readnbt(nbt); } super.load(nbt);
readnbt(nbt);
}
@Override @Override
protected void saveAdditional(CompoundTag nbt) protected void saveAdditional(CompoundTag nbt) {
{ super.saveAdditional(nbt); writenbt(nbt); } super.saveAdditional(nbt);
writenbt(nbt);
}
@Override @Override
public void setRemoved() public void setRemoved() {
{
super.setRemoved(); super.setRemoved();
fluid_handler_.invalidate(); fluid_handler_.invalidate();
} }
@ -225,21 +235,18 @@ public class EdFluidFunnel
// ICapabilityProvider / Output flow handler ---------------------------------------------------------- // ICapabilityProvider / Output flow handler ----------------------------------------------------------
@Override @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(); if (capability == ForgeCapabilities.FLUID_HANDLER) return fluid_handler_.cast();
return super.getCapability(capability, facing); return super.getCapability(capability, facing);
} }
// ----------------------------------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------------------------------
private FluidState get_fluidstate(BlockPos pos) private FluidState get_fluidstate(BlockPos pos) {
{
return level.getFluidState(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; if (!fluidstate.isSource()) return false;
IFluidHandler hnd = Fluidics.handler(level, pos, null); IFluidHandler hnd = Fluidics.handler(level, pos, null);
FluidStack fs; 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. 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()) { if (tank_.isEmpty()) {
tank_.setFluid(fs.copy()); tank_.setFluid(fs.copy());
} else if (tank_.isFluidEqual(fs)) { } else if (tank_.isFluidEqual(fs)) {
@ -265,8 +273,7 @@ public class EdFluidFunnel
return true; return true;
} }
private boolean can_pick(BlockPos pos, FluidState fluidstate) private boolean can_pick(BlockPos pos, FluidState fluidstate) {
{
if (fluidstate.isSource()) return true; if (fluidstate.isSource()) return true;
final IFluidHandler hnd = Fluidics.handler(level, pos, null); final IFluidHandler hnd = Fluidics.handler(level, pos, null);
if (hnd == null) return false; if (hnd == null) return false;
@ -274,8 +281,7 @@ public class EdFluidFunnel
return ((fs != null) && (!fs.isEmpty())) && (fluidstate.getType().isSame(fs.getFluid())); 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_ = new ArrayList<>(9);
search_offsets_.add(new Vec3i(0, 1, 0)); // up first 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); FluidState collection_fluidstate = get_fluidstate(collection_pos);
if (collection_fluidstate.isEmpty()) return false; if (collection_fluidstate.isEmpty()) return false;
Fluid fluid_to_collect = collection_fluidstate.getType(); Fluid fluid_to_collect = collection_fluidstate.getType();
if ((!tank_.isEmpty()) && (!tank_.getFluid().getFluid().isSame(fluid_to_collect))) return false; 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 (try_pick(collection_pos, collection_fluidstate)) {
if((last_pick_pos_==null) || (last_pick_pos_.distSqr(collection_pos) > MAX_TRACK_RADIUS_SQ)) { last_pick_pos_ = collection_pos; search_offsets_ = null; } 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_; BlockPos pos = last_pick_pos_;
HashSet<BlockPos> checked = new HashSet<>(); HashSet<BlockPos> checked = new HashSet<>();
Stack<BlockPos> trail = new Stack<>(); Stack<BlockPos> trail = new Stack<>();
@ -305,7 +316,10 @@ public class EdFluidFunnel
checked.add(pos); checked.add(pos);
int steps = 0; int steps = 0;
boolean intensive = (no_fluid_found_counter_ >= INTENSIVE_SEARCH_TRIGGER_THRESHOLD); 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); if (search_offsets_ == null) rebuild_search_offsets(intensive);
int max = intensive ? MAX_TRACKING_STEPS_PER_CYCLE_INTENSIVE : MAX_TRACKING_STEPS_PER_CYCLE; int max = intensive ? MAX_TRACKING_STEPS_PER_CYCLE_INTENSIVE : MAX_TRACKING_STEPS_PER_CYCLE;
while (++steps <= max) { while (++steps <= max) {
@ -336,7 +350,8 @@ public class EdFluidFunnel
no_fluid_found_counter_ = 0; no_fluid_found_counter_ = 0;
search_offsets_ = null; search_offsets_ = null;
// probability reset, so it's not turteling too far away, mainly for large nether lava seas, not desert lakes. // 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))); //println("PASS " + steps + " - " + (pos.subtract(collection_pos)));
return true; return true;
} }
@ -354,8 +369,7 @@ public class EdFluidFunnel
return false; return false;
} }
public void tick() public void tick() {
{
if ((level.isClientSide) || (--tick_timer_ > 0)) return; if ((level.isClientSide) || (--tick_timer_ > 0)) return;
tick_timer_ = TICK_INTERVAL; tick_timer_ = TICK_INTERVAL;
collection_timer_ += TICK_INTERVAL; collection_timer_ += TICK_INTERVAL;
@ -399,7 +413,8 @@ public class EdFluidFunnel
} }
// Block state // Block state
int fill_level = (tank_ == null) ? 0 : (Mth.clamp(tank_.getFluidAmount() / 1000, 0, FluidFunnelBlock.FILL_LEVEL_MAX)); 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(); if (dirty) setChanged();
} }
} }

View file

@ -9,6 +9,11 @@
*/ */
package dev.zontreck.engineerdecor.blocks; 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.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag; 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.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level; 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.Block;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockBehaviour; 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.energy.IEnergyStorage;
import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.items.IItemHandler; 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.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class EdFreezer public class EdFreezer {
{ public static void on_config(int consumption, int cooldown_per_second) {
public static void on_config(int consumption, int cooldown_per_second) FreezerTileEntity.on_config(consumption, cooldown_per_second);
{ FreezerTileEntity.on_config(consumption, cooldown_per_second); } }
//-------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------
// Block // 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 int PHASE_MAX = 4;
public static final IntegerProperty PHASE = IntegerProperty.create("phase", 0, PHASE_MAX); public static final IntegerProperty PHASE = IntegerProperty.create("phase", 0, PHASE_MAX);
public FreezerBlock(long config, BlockBehaviour.Properties builder, final AABB unrotatedAABB) public FreezerBlock(long config, BlockBehaviour.Properties builder, final AABB unrotatedAABB) {
{ super(config, builder, unrotatedAABB); } super(config, builder, unrotatedAABB);
}
@Override @Override
public boolean isBlockEntityTicking(Level world, BlockState state) public boolean isBlockEntityTicking(Level world, BlockState state) {
{ return true; } return true;
}
@Override @Override
public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) {
{ return Shapes.block(); } return Shapes.block();
}
@Override @Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
{ super.createBlockStateDefinition(builder); builder.add(PHASE); } super.createBlockStateDefinition(builder);
builder.add(PHASE);
}
@Override @Override
@Nullable @Nullable
public BlockState getStateForPlacement(BlockPlaceContext context) public BlockState getStateForPlacement(BlockPlaceContext context) {
{ return super.getStateForPlacement(context).setValue(PHASE, 0); } return super.getStateForPlacement(context).setValue(PHASE, 0);
}
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public boolean hasAnalogOutputSignal(BlockState state) public boolean hasAnalogOutputSignal(BlockState state) {
{ return true; } return true;
}
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public int getAnalogOutputSignal(BlockState state, Level world, BlockPos pos) public int getAnalogOutputSignal(BlockState state, Level world, BlockPos pos) {
{ return Mth.clamp((state.getValue(PHASE)*4), 0, 15); } return Mth.clamp((state.getValue(PHASE) * 4), 0, 15);
}
@Override @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 @Override
public boolean hasDynamicDropList() public boolean hasDynamicDropList() {
{ return true; } return true;
}
@Override @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<>(); final List<ItemStack> stacks = new ArrayList<>();
if (world.isClientSide) return stacks; if (world.isClientSide) return stacks;
if (!(te instanceof FreezerTileEntity)) return stacks; if (!(te instanceof FreezerTileEntity)) return stacks;
@ -121,8 +128,7 @@ public class EdFreezer
@Override @Override
@SuppressWarnings("deprecation") @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 (player.isShiftKeyDown()) return InteractionResult.PASS;
if (world.isClientSide()) return InteractionResult.SUCCESS; if (world.isClientSide()) return InteractionResult.SUCCESS;
FreezerTileEntity te = getTe(world, pos); FreezerTileEntity te = getTe(world, pos);
@ -150,25 +156,27 @@ public class EdFreezer
} }
@Override @Override
public boolean shouldCheckWeakPower(BlockState state, LevelReader world, BlockPos pos, Direction side) public boolean shouldCheckWeakPower(BlockState state, SignalGetter level, BlockPos pos, Direction side) {
{ return false; } return false;
}
@Override @Override
@OnlyIn(Dist.CLIENT) @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 @Nullable
private FreezerTileEntity getTe(Level world, BlockPos pos) private FreezerTileEntity getTe(Level world, BlockPos pos) {
{ final BlockEntity te=world.getBlockEntity(pos); return (!(te instanceof FreezerTileEntity)) ? (null) : ((FreezerTileEntity)te); } final BlockEntity te = world.getBlockEntity(pos);
return (!(te instanceof FreezerTileEntity)) ? (null) : ((FreezerTileEntity) te);
}
} }
//-------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------
// Tile entity // 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 TICK_INTERVAL = 20;
public static final int MAX_FLUID_LEVEL = 2000; public static final int MAX_FLUID_LEVEL = 2000;
public static final int MAX_ENERGY_BUFFER = 32000; 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 cooldown_rate = DEFAULT_COOLDOWN_RATE;
private static int reheat_rate = 1; 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 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 tick_timer_;
private int energy_stored_; private int energy_stored_;
private int progress_; private int progress_;
private boolean force_block_update_; 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); energy_consumption = Mth.clamp(consumption, 8, 4096);
cooldown_rate = Mth.clamp(cooldown_per_second, 1, 5); cooldown_rate = Mth.clamp(cooldown_per_second, 1, 5);
reheat_rate = Mth.clamp(cooldown_per_second / 2, 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."); ModConfig.log("Config freezer energy consumption:" + energy_consumption + "rf/t, cooldown-rate: " + cooldown_rate + "%/s.");
} }
public FreezerTileEntity(BlockPos pos, BlockState state) public int progress() {
{ super(ModContent.getBlockEntityTypeOfBlock(state.getBlock()), pos, state); } return progress_;
}
public int progress() public int phase() {
{ return progress_; }
public int phase()
{
if (tank_.getFluidAmount() < 1000) return PHASE_EMPTY; if (tank_.getFluidAmount() < 1000) return PHASE_EMPTY;
if (progress_ >= 100) return PHASE_BLUEICE; if (progress_ >= 100) return PHASE_BLUEICE;
if (progress_ >= 70) return PHASE_PACKEDICE; if (progress_ >= 70) return PHASE_PACKEDICE;
@ -214,156 +225,125 @@ public class EdFreezer
return PHASE_WATER; return PHASE_WATER;
} }
public ItemStack getIceItem(boolean extract) public ItemStack getIceItem(boolean extract) {
{
ItemStack stack; ItemStack stack;
switch (phase()) { switch (phase()) {
case PHASE_ICE: stack = new ItemStack(Items.ICE); break; case PHASE_ICE:
case PHASE_PACKEDICE: stack = new ItemStack(Items.PACKED_ICE); break; stack = new ItemStack(Items.ICE);
case PHASE_BLUEICE: stack = new ItemStack(Items.BLUE_ICE); break; break;
default: return ItemStack.EMPTY; 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(); if (extract) reset_process();
return stack; return stack;
} }
public int comparator_signal() public int comparator_signal() {
{ return phase() * 4; } return phase() * 4;
}
protected void reset_process() // BlockEntity ------------------------------------------------------------------------------
{
protected void reset_process() {
force_block_update_ = true; force_block_update_ = true;
tank_.drain(1000); tank_.drain(1000);
tick_timer_ = 0; tick_timer_ = 0;
progress_ = 0; progress_ = 0;
} }
public void readnbt(CompoundTag nbt) public void readnbt(CompoundTag nbt) {
{
energy_stored_ = nbt.getInt("energy"); energy_stored_ = nbt.getInt("energy");
progress_ = nbt.getInt("progress"); progress_ = nbt.getInt("progress");
tank_.load(nbt); 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("energy", Mth.clamp(energy_stored_, 0, MAX_ENERGY_BUFFER));
nbt.putInt("progress", Mth.clamp(progress_, 0, 100)); nbt.putInt("progress", Mth.clamp(progress_, 0, 100));
tank_.save(nbt); tank_.save(nbt);
} }
// BlockEntity ------------------------------------------------------------------------------ // IItemHandler --------------------------------------------------------------------------------
@Override @Override
public void load(CompoundTag nbt) public void load(CompoundTag nbt) {
{ super.load(nbt); readnbt(nbt); } super.load(nbt);
readnbt(nbt);
}
@Override @Override
protected void saveAdditional(CompoundTag nbt) protected void saveAdditional(CompoundTag nbt) {
{ super.saveAdditional(nbt); writenbt(nbt); } super.saveAdditional(nbt);
writenbt(nbt);
}
// IFluidHandler --------------------------------------------------------------------------------
@Override @Override
public void setRemoved() public void setRemoved() {
{
super.setRemoved(); super.setRemoved();
energy_handler_.invalidate(); energy_handler_.invalidate();
fluid_handler_.invalidate(); fluid_handler_.invalidate();
item_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 ---------------------------------------------------------------------------- // IEnergyStorage ----------------------------------------------------------------------------
protected LazyOptional<IEnergyStorage> energy_handler_ = LazyOptional.of(() -> this); @Override
public boolean canExtract() {
return false;
}
@Override @Override
public boolean canExtract() public boolean canReceive() {
{ return false; } return true;
}
@Override @Override
public boolean canReceive() public int getMaxEnergyStored() {
{ return true; } return MAX_ENERGY_BUFFER;
}
@Override @Override
public int getMaxEnergyStored() public int getEnergyStored() {
{ return MAX_ENERGY_BUFFER; } return energy_stored_;
}
@Override @Override
public int getEnergyStored() public int extractEnergy(int maxExtract, boolean simulate) {
{ return energy_stored_; } return 0;
}
@Override @Override
public int extractEnergy(int maxExtract, boolean simulate) public int receiveEnergy(int maxReceive, boolean simulate) {
{ return 0; }
@Override
public int receiveEnergy(int maxReceive, boolean simulate)
{
if (energy_stored_ >= MAX_ENERGY_BUFFER) return 0; if (energy_stored_ >= MAX_ENERGY_BUFFER) return 0;
int n = Math.min(maxReceive, (MAX_ENERGY_BUFFER - energy_stored_)); int n = Math.min(maxReceive, (MAX_ENERGY_BUFFER - energy_stored_));
if (n > MAX_ENERGY_TRANSFER) n = MAX_ENERGY_TRANSFER; if (n > MAX_ENERGY_TRANSFER) n = MAX_ENERGY_TRANSFER;
if(!simulate) {energy_stored_ += n; setChanged(); } if (!simulate) {
energy_stored_ += n;
setChanged();
}
return n; return n;
} }
// Capability export ----------------------------------------------------------------------------
@Override @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.ITEM_HANDLER) return item_handler_.cast();
if (capability == ForgeCapabilities.FLUID_HANDLER) return fluid_handler_.cast(); if (capability == ForgeCapabilities.FLUID_HANDLER) return fluid_handler_.cast();
if (capability == ForgeCapabilities.ENERGY) return energy_handler_.cast(); if (capability == ForgeCapabilities.ENERGY) return energy_handler_.cast();
return super.getCapability(capability, facing); return super.getCapability(capability, facing);
} }
// ITickable ------------------------------------------------------------------------------------ // Capability export ----------------------------------------------------------------------------
@Override @Override
public void tick() public void tick() {
{
if (level.isClientSide) return; if (level.isClientSide) return;
if (--tick_timer_ > 0) return; if (--tick_timer_ > 0) return;
tick_timer_ = TICK_INTERVAL; tick_timer_ = TICK_INTERVAL;
@ -397,5 +377,48 @@ public class EdFreezer
} }
if (dirty) setChanged(); 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; 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.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.core.particles.ParticleTypes; 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.item.crafting.SmeltingRecipe;
import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level; 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.Block;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockBehaviour; 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.event.ForgeEventFactory;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.registries.ForgeRegistries; 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 javax.annotation.Nullable;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class EdFurnace public class EdFurnace {
{ public static void on_config(int speed_percent, int fuel_efficiency_percent, int boost_energy_per_tick, String accepted_heaters_csv) {
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);
{ FurnaceTileEntity.on_config(speed_percent, fuel_efficiency_percent, boost_energy_per_tick, accepted_heaters_csv); } }
//-------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------
// Block // 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 static final BooleanProperty LIT = BlockStateProperties.LIT;
public FurnaceBlock(long config, BlockBehaviour.Properties properties, final AABB[] unrotatedAABB) public FurnaceBlock(long config, BlockBehaviour.Properties properties, final AABB[] unrotatedAABB) {
{ super(config, properties, unrotatedAABB); registerDefaultState(super.defaultBlockState().setValue(LIT, false)); } super(config, properties, unrotatedAABB);
registerDefaultState(super.defaultBlockState().setValue(LIT, false));
}
@Override @Override
public boolean isBlockEntityTicking(Level world, BlockState state) public boolean isBlockEntityTicking(Level world, BlockState state) {
{ return true; } return true;
}
@Override @Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
{ super.createBlockStateDefinition(builder); builder.add(LIT); } super.createBlockStateDefinition(builder);
builder.add(LIT);
}
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public int getLightEmission(BlockState state, BlockGetter world, BlockPos pos) public int getLightEmission(BlockState state, BlockGetter world, BlockPos pos) {
{ return state.getValue(LIT) ? super.getLightEmission(state, world, pos) : 0; } return state.getValue(LIT) ? super.getLightEmission(state, world, pos) : 0;
}
@Override @Override
@Nullable @Nullable
public BlockState getStateForPlacement(BlockPlaceContext context) public BlockState getStateForPlacement(BlockPlaceContext context) {
{ return super.getStateForPlacement(context).setValue(LIT, false); } return super.getStateForPlacement(context).setValue(LIT, false);
}
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public boolean hasAnalogOutputSignal(BlockState state) public boolean hasAnalogOutputSignal(BlockState state) {
{ return true; } return true;
}
@Override @Override
@SuppressWarnings("deprecation") @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); BlockEntity te = world.getBlockEntity(pos);
return (te instanceof FurnaceTileEntity) ? ((FurnaceTileEntity) te).getComparatorOutput() : 0; return (te instanceof FurnaceTileEntity) ? ((FurnaceTileEntity) te).getComparatorOutput() : 0;
} }
@Override @Override
public boolean shouldCheckWeakPower(BlockState state, LevelReader world, BlockPos pos, Direction side) public boolean shouldCheckWeakPower(BlockState state, SignalGetter level, BlockPos pos, Direction side) {
{ return false; } return false;
}
@Override @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)); world.setBlockAndUpdate(pos, state.setValue(LIT, false));
if (world.isClientSide) return; if (world.isClientSide) return;
if ((!stack.hasTag()) || (!stack.getTag().contains("inventory"))) return; if ((!stack.hasTag()) || (!stack.getTag().contains("inventory"))) return;
@ -138,8 +137,9 @@ public class EdFurnace
} }
@Override @Override
public boolean hasDynamicDropList() public boolean hasDynamicDropList() {
{ return true; } return true;
}
@Override @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) {
@ -164,19 +164,20 @@ public class EdFurnace
@Override @Override
@SuppressWarnings("deprecation") @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) {
{ return useOpenGui(state, world, pos, player); } return useOpenGui(state, world, pos, player);
}
@Override @Override
@OnlyIn(Dist.CLIENT) @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; if ((state.getBlock() != this) || (!state.getValue(LIT))) return;
final double rv = rnd.nextDouble(); final double rv = rnd.nextDouble();
if (rv > 0.5) return; if (rv > 0.5) return;
final double x = 0.5 + pos.getX(), y = 0.5 + pos.getY(), z = 0.5 + pos.getZ(); 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); 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)) { switch (state.getValue(HORIZONTAL_FACING)) {
case WEST -> world.addParticle(ParticleTypes.SMOKE, x - xc, yr, z + xr, 0.0, 0.0, 0.0); 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); 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 // 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 RecipeType<SmeltingRecipe> RECIPE_TYPE = RecipeType.SMELTING;
private static final int MAX_BURNTIME = 0x7fff; private static final int MAX_BURNTIME = 0x7fff;
private static final int MAX_XP_STORED = 65535; private static final int MAX_XP_STORED = 65535;
@ -215,40 +215,18 @@ public class EdFurnace
private static final int AUX_1_SLOT_NO = 10; private static final int AUX_1_SLOT_NO = 10;
// Config ---------------------------------------------------------------------------------- // Config ----------------------------------------------------------------------------------
private static final Set<Item> accepted_heaters_ = new HashSet<>();
private static double proc_fuel_efficiency_ = 1.0; private static double proc_fuel_efficiency_ = 1.0;
private static double proc_speed_ = 1.2; private static double proc_speed_ = 1.2;
private static int boost_energy_consumption = DEFAULT_BOOST_ENERGY * TICK_INTERVAL; private static int boost_energy_consumption = DEFAULT_BOOST_ENERGY * TICK_INTERVAL;
private static final Set<Item> accepted_heaters_ = new HashSet<>(); private final Inventories.StorageInventory inventory_;
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(",")) + ".");
}
// DecorFurnaceTileEntity ----------------------------------------------------------------------------- // 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 tick_timer_;
private int fifo_timer_; private int fifo_timer_;
private double proc_time_elapsed_; private double proc_time_elapsed_;
@ -259,21 +237,42 @@ public class EdFurnace
private @Nullable Recipe<?> current_recipe_ = null; private @Nullable Recipe<?> current_recipe_ = null;
private int fuel_burntime_; private int fuel_burntime_;
private int field_proc_time_elapsed_; private int field_proc_time_elapsed_;
private boolean heater_inserted_ = false; protected final ContainerData fields = new ContainerData() {
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) {
@Override @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); ItemStack slot_stack = stacks_.get(index);
boolean already_in_slot = (!stack.isEmpty()) && (Inventories.areItemStacksIdentical(stack, slot_stack)); boolean already_in_slot = (!stack.isEmpty()) && (Inventories.areItemStacksIdentical(stack, slot_stack));
stacks_.set(index, 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(); CompoundTag nbt = new CompoundTag();
writenbt(nbt); writenbt(nbt);
reset(); reset();
return nbt; return nbt;
} }
public void reset() public void reset() {
{
inventory_.clearContent(); inventory_.clearContent();
proc_time_elapsed_ = 0; proc_time_elapsed_ = 0;
proc_time_needed_ = 0; proc_time_needed_ = 0;
@ -338,8 +384,7 @@ public class EdFurnace
current_recipe_ = null; current_recipe_ = null;
} }
public void readnbt(CompoundTag nbt) public void readnbt(CompoundTag nbt) {
{
burntime_left_ = nbt.getInt("BurnTime"); burntime_left_ = nbt.getInt("BurnTime");
proc_time_elapsed_ = nbt.getInt("CookTime"); proc_time_elapsed_ = nbt.getInt("CookTime");
proc_time_needed_ = nbt.getInt("CookTimeTotal"); proc_time_needed_ = nbt.getInt("CookTimeTotal");
@ -349,8 +394,9 @@ public class EdFurnace
inventory_.load(nbt); 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("BurnTime", Mth.clamp(burntime_left_, 0, MAX_BURNTIME));
nbt.putInt("CookTime", Mth.clamp((int) proc_time_elapsed_, 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)); nbt.putInt("CookTimeTotal", Mth.clamp(proc_time_needed_, 0, MAX_BURNTIME));
@ -360,8 +406,7 @@ public class EdFurnace
inventory_.save(nbt); 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()) { 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 return 0; // fuel completely empty
} else { } else {
@ -373,19 +418,22 @@ public class EdFurnace
} }
} }
// BlockEntity ------------------------------------------------------------------------------ @Override
public void load(CompoundTag nbt) {
super.load(nbt);
readnbt(nbt);
}
// IContainerProvider ----------------------------------------------------------------------
@Override @Override
public void load(CompoundTag nbt) protected void saveAdditional(CompoundTag nbt) {
{ super.load(nbt); readnbt(nbt); } super.saveAdditional(nbt);
writenbt(nbt);
}
@Override @Override
protected void saveAdditional(CompoundTag nbt) public void setRemoved() {
{ super.saveAdditional(nbt); writenbt(nbt); }
@Override
public void setRemoved()
{
super.setRemoved(); super.setRemoved();
item_extraction_handler_.invalidate(); item_extraction_handler_.invalidate();
item_insertion_handler_.invalidate(); item_insertion_handler_.invalidate();
@ -393,68 +441,41 @@ public class EdFurnace
energy_handler_.invalidate(); 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 ----------------------------------------------------------------------------------------------- // Fields -----------------------------------------------------------------------------------------------
protected final ContainerData fields = new ContainerData()
{
@Override @Override
public int getCount() public Component getName() {
{ return FurnaceTileEntity.NUM_OF_FIELDS; } return Auxiliaries.localizable(getBlockState().getBlock().getDescriptionId());
@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;
}
}
};
// Capability export ---------------------------------------------------------------------------- // Capability export ----------------------------------------------------------------------------
@Override @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 (capability == ForgeCapabilities.ITEM_HANDLER) {
if (facing == Direction.UP) return item_insertion_handler_.cast(); if (facing == Direction.UP) return item_insertion_handler_.cast();
if (facing == Direction.DOWN) return item_extraction_handler_.cast(); if (facing == Direction.DOWN) return item_extraction_handler_.cast();
@ -465,11 +486,8 @@ public class EdFurnace
return super.getCapability(capability, facing); return super.getCapability(capability, facing);
} }
// ITickableTileEntity -------------------------------------------------------------------------
@Override @Override
public void tick() public void tick() {
{
if (--tick_timer_ > 0) return; if (--tick_timer_ > 0) return;
tick_timer_ = TICK_INTERVAL; tick_timer_ = TICK_INTERVAL;
final BlockState state = level.getBlockState(worldPosition); final BlockState state = level.getBlockState(worldPosition);
@ -508,7 +526,8 @@ public class EdFurnace
if (!fuel.isEmpty()) { if (!fuel.isEmpty()) {
Item fuel_item = fuel.getItem(); Item fuel_item = fuel.getItem();
fuel.shrink(1); 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_; field_proc_time_elapsed_ = (int) proc_time_elapsed_;
} }
// Furnace ------------------------------------------------------------------------------------- public boolean burning() {
return burntime_left_ > 0;
@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() public int getSmeltingTimeNeeded(Level world, ItemStack stack) {
{ return burntime_left_ > 0; }
public int getSmeltingTimeNeeded(Level world, ItemStack stack)
{
if (stack.isEmpty()) return 0; if (stack.isEmpty()) return 0;
AbstractCookingRecipe recipe = getSmeltingResult(RECIPE_TYPE, world, stack); AbstractCookingRecipe recipe = getSmeltingResult(RECIPE_TYPE, world, stack);
if (recipe == null) return 0; if (recipe == null) return 0;
@ -563,8 +571,7 @@ public class EdFurnace
return (t <= 0) ? DEFAULT_SMELTING_TIME : t; 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); ItemStack from = inventory_.getItem(index_from);
if (from.isEmpty()) return false; if (from.isEmpty()) return false;
ItemStack to = inventory_.getItem(index_to); ItemStack to = inventory_.getItem(index_to);
@ -593,20 +600,19 @@ public class EdFurnace
return changed; return changed;
} }
protected boolean canSmeltCurrentItem() protected boolean canSmeltCurrentItem() {
{
if ((currentRecipe() == null) || (inventory_.getItem(SMELTING_INPUT_SLOT_NO).isEmpty())) return false; if ((currentRecipe() == null) || (inventory_.getItem(SMELTING_INPUT_SLOT_NO).isEmpty())) return false;
final ItemStack recipe_result_items = getSmeltingResult(inventory_.getItem(SMELTING_INPUT_SLOT_NO)); final ItemStack recipe_result_items = getSmeltingResult(inventory_.getItem(SMELTING_INPUT_SLOT_NO));
if (recipe_result_items.isEmpty()) return false; if (recipe_result_items.isEmpty()) return false;
final ItemStack result_stack = inventory_.getItem(SMELTING_OUTPUT_SLOT_NO); final ItemStack result_stack = inventory_.getItem(SMELTING_OUTPUT_SLOT_NO);
if (result_stack.isEmpty()) return true; if (result_stack.isEmpty()) return true;
if(!result_stack.sameItem(recipe_result_items)) return false; 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; 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(); return result_stack.getCount() + recipe_result_items.getCount() <= recipe_result_items.getMaxStackSize();
} }
protected void smeltCurrentItem() protected void smeltCurrentItem() {
{
if (!canSmeltCurrentItem()) return; if (!canSmeltCurrentItem()) return;
final ItemStack smelting_input_stack = inventory_.getItem(SMELTING_INPUT_SLOT_NO); final ItemStack smelting_input_stack = inventory_.getItem(SMELTING_INPUT_SLOT_NO);
final ItemStack recipe_result_items = getSmeltingResult(smelting_input_stack); final ItemStack recipe_result_items = getSmeltingResult(smelting_input_stack);
@ -621,18 +627,7 @@ public class EdFurnace
xp_stored_ += xp; xp_stored_ += xp;
} }
public static int getFuelBurntime(Level world, ItemStack stack) public int consumeSmeltingExperience(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)
{
if (xp_stored_ < 1) return 0; if (xp_stored_ < 1) return 0;
float xp = xp_stored_; float xp = xp_stored_;
if (xp >= 15) xp /= 2; if (xp >= 15) xp /= 2;
@ -641,119 +636,48 @@ public class EdFurnace
return (int) xp; return (int) xp;
} }
public ItemStack getSmeltingResult(final ItemStack stack) public ItemStack getSmeltingResult(final ItemStack stack) {
{ return (currentRecipe()==null) ? (ItemStack.EMPTY) : (currentRecipe().getResultItem()); } 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); float xp = (currentRecipe() instanceof AbstractCookingRecipe) ? (((AbstractCookingRecipe) currentRecipe()).getExperience()) : (0);
return (xp <= 0) ? 0.7f : xp; // default value for recipes without defined xp 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 @Nullable
protected Recipe<?> currentRecipe() protected Recipe<?> currentRecipe() {
{ return current_recipe_; } return current_recipe_;
}
protected void updateCurrentRecipe() protected void updateCurrentRecipe() {
{ setCurrentRecipe(getSmeltingResult(RECIPE_TYPE, getLevel(), inventory_.getItem(SMELTING_INPUT_SLOT_NO))); } setCurrentRecipe(getSmeltingResult(RECIPE_TYPE, getLevel(), inventory_.getItem(SMELTING_INPUT_SLOT_NO)));
}
protected void setCurrentRecipe(Recipe<?> recipe) protected void setCurrentRecipe(Recipe<?> recipe) {
{ current_recipe_ = recipe; } current_recipe_ = recipe;
}
} }
//-------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------
// Container slots // Container slots
//-------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------
public static class FurnaceContainer extends AbstractContainerMenu implements Networking.INetworkSynchronisableContainer public static class FurnaceContainer extends AbstractContainerMenu implements Networking.INetworkSynchronisableContainer {
{
// Slots -------------------------------------------------------------------------------------------- // 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; private static final int PLAYER_INV_START_SLOTNO = 11;
protected final Player player_; protected final Player player_;
// Container ----------------------------------------------------------------------------------------
protected final Container inventory_; protected final Container inventory_;
protected final ContainerLevelAccess wpc_; protected final ContainerLevelAccess wpc_;
private final ContainerData fields_; private final ContainerData fields_;
private final RecipeType<? extends AbstractCookingRecipe> recipe_type_; private final RecipeType<? extends AbstractCookingRecipe> recipe_type_;
public FurnaceContainer(int cid, Inventory player_inventory) {
public int field(int index) { return fields_.get(index); } this(cid, player_inventory, new SimpleContainer(FurnaceTileEntity.NUM_OF_SLOTS), ContainerLevelAccess.NULL, new SimpleContainerData(FurnaceTileEntity.NUM_OF_FIELDS));
public Player player() { return player_ ; } }
public Container inventory() { return inventory_ ; } private FurnaceContainer(int cid, Inventory player_inventory, Container block_inventory, ContainerLevelAccess wpc, ContainerData fields) {
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)
{
super(ModContent.getMenuType("small_lab_furnace"), cid); // @todo: class mapping super(ModContent.getMenuType("small_lab_furnace"), cid); // @todo: class mapping
player_ = player_inventory.player; player_ = player_inventory.player;
inventory_ = block_inventory; inventory_ = block_inventory;
@ -782,29 +706,49 @@ public class EdFurnace
this.addDataSlots(fields_); // === Add reference holders this.addDataSlots(fields_); // === Add reference holders
} }
@Override public int field(int index) {
public boolean stillValid(Player player) return fields_.get(index);
{ return inventory_.stillValid(player); } }
public Player player() {
return player_;
}
public Container inventory() {
return inventory_;
}
public Level world() {
return player_.level();
}
@Override @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); Slot slot = getSlot(index);
if ((slot == null) || (!slot.hasItem())) return ItemStack.EMPTY; if ((slot == null) || (!slot.hasItem())) return ItemStack.EMPTY;
ItemStack slot_stack = slot.getItem(); ItemStack slot_stack = slot.getItem();
ItemStack transferred = slot_stack.copy(); ItemStack transferred = slot_stack.copy();
if ((index == 2) || (index == 7) || (index == 8)) { if ((index == 2) || (index == 7) || (index == 8)) {
// Output slots // 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); slot.onQuickCraft(slot_stack, transferred);
} else if ((index == 0) || (index == 3) || (index == 4)) { } else if ((index == 0) || (index == 3) || (index == 4)) {
// Input slots // 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)) { } else if ((index == 1) || (index == 5) || (index == 6)) {
// Fuel slots // 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)) { } 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)) { } else if ((index >= PLAYER_INV_START_SLOTNO) && (index <= PLAYER_INV_START_SLOTNO + 36)) {
// Player inventory // Player inventory
if (FurnaceTileEntity.canSmelt(world(), slot_stack)) { if (FurnaceTileEntity.canSmelt(world(), slot_stack)) {
@ -813,7 +757,7 @@ public class EdFurnace
(!moveItemStackTo(slot_stack, 3, 4, false)) && // fifo0 (!moveItemStackTo(slot_stack, 3, 4, false)) && // fifo0
(!moveItemStackTo(slot_stack, 4, 5, false)) // fifo1 (!moveItemStackTo(slot_stack, 4, 5, false)) // fifo1
) return ItemStack.EMPTY; ) return ItemStack.EMPTY;
} else if(FurnaceTileEntity.isFuel(player_.level, slot_stack)) { } else if (FurnaceTileEntity.isFuel(player_.level(), slot_stack)) {
if ( if (
(!moveItemStackTo(slot_stack, 1, 2, false)) && // fuel input (!moveItemStackTo(slot_stack, 1, 2, false)) && // fuel input
(!moveItemStackTo(slot_stack, 5, 6, false)) && // fuel fifo0 (!moveItemStackTo(slot_stack, 5, 6, false)) && // fuel fifo0
@ -821,7 +765,8 @@ public class EdFurnace
) return ItemStack.EMPTY; ) return ItemStack.EMPTY;
} else if ((index >= PLAYER_INV_START_SLOTNO) && (index < PLAYER_INV_START_SLOTNO + 27)) { } else if ((index >= PLAYER_INV_START_SLOTNO) && (index < PLAYER_INV_START_SLOTNO + 27)) {
// player inventory --> player hotbar // 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))) { } 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 // player hotbar --> player inventory
return ItemStack.EMPTY; return ItemStack.EMPTY;
@ -841,27 +786,102 @@ public class EdFurnace
return transferred; return transferred;
} }
// INetworkSynchronisableContainer --------------------------------------------------------- @OnlyIn(Dist.CLIENT)
public void onGuiAction(CompoundTag nbt) {
Networking.PacketContainerSyncClientToServer.sendToServer(containerId, nbt);
}
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public void onGuiAction(CompoundTag nbt) public void onGuiAction(String key, int value) {
{ Networking.PacketContainerSyncClientToServer.sendToServer(containerId, nbt); }
@OnlyIn(Dist.CLIENT)
public void onGuiAction(String key, int value)
{
CompoundTag nbt = new CompoundTag(); CompoundTag nbt = new CompoundTag();
nbt.putInt(key, value); nbt.putInt(key, value);
Networking.PacketContainerSyncClientToServer.sendToServer(containerId, nbt); Networking.PacketContainerSyncClientToServer.sendToServer(containerId, nbt);
} }
@Override // INetworkSynchronisableContainer ---------------------------------------------------------
public void onServerPacketReceived(int windowId, CompoundTag nbt)
{}
@Override @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) @OnlyIn(Dist.CLIENT)
public static class FurnaceGui extends Guis.ContainerGui<FurnaceContainer> public static class FurnaceGui extends Guis.ContainerGui<FurnaceContainer> {
{ public FurnaceGui(FurnaceContainer container, Inventory player_inventory, Component title) {
public FurnaceGui(FurnaceContainer container, Inventory player_inventory, Component title) super(container, player_inventory, title, "textures/gui/small_lab_furnace_gui.png");
{ super(container, player_inventory, title, "textures/gui/small_lab_furnace_gui.png"); } }
@Override @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; final int x0 = leftPos, y0 = topPos, w = imageWidth, h = imageHeight;
if (getMenu().field(4) != 0) { if (getMenu().field(4) != 0) {
final int k = flame_px(13); 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) 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); } 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) private int flame_px(int pixels) {
{ int ibt = getMenu().field(1); return ((getMenu().field(0) * pixels) / ((ibt>0) ? (ibt) : (FurnaceTileEntity.DEFAULT_SMELTING_TIME))); } 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; 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.core.Direction;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.world.item.DyeColor; 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.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import dev.zontreck.engineerdecor.libmc.StandardBlocks;
import dev.zontreck.engineerdecor.libmc.Auxiliaries;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.List; import java.util.List;
public class EdGlassBlock extends StainedGlassBlock implements StandardBlocks.IStandardBlock public class EdGlassBlock extends StainedGlassBlock implements StandardBlocks.IStandardBlock {
{ public EdGlassBlock(long config, BlockBehaviour.Properties properties) {
public EdGlassBlock(long config, BlockBehaviour.Properties properties) super(DyeColor.BLACK, properties);
{ super(DyeColor.BLACK, properties); } }
@Override @Override
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public void appendHoverText(ItemStack stack, @Nullable BlockGetter world, List<Component> tooltip, TooltipFlag flag) public void appendHoverText(ItemStack stack, @Nullable BlockGetter world, List<Component> tooltip, TooltipFlag flag) {
{ Auxiliaries.Tooltip.addInformation(stack, world, tooltip, flag, true); } Auxiliaries.Tooltip.addInformation(stack, world, tooltip, flag, true);
}
@Override @Override
public StandardBlocks.IStandardBlock.RenderTypeHint getRenderTypeHint() public StandardBlocks.IStandardBlock.RenderTypeHint getRenderTypeHint() {
{ return StandardBlocks.IStandardBlock.RenderTypeHint.TRANSLUCENT; } return StandardBlocks.IStandardBlock.RenderTypeHint.TRANSLUCENT;
}
@Override @Override
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public boolean skipRendering(BlockState state, BlockState adjacentBlockState, Direction side) public boolean skipRendering(BlockState state, BlockState adjacentBlockState, Direction side) {
{ return (adjacentBlockState.getBlock()==this) || (super.skipRendering(state, adjacentBlockState, side)); } return (adjacentBlockState.getBlock() == this) || (super.skipRendering(state, adjacentBlockState, side));
}
@Override @Override
public boolean isPossibleToRespawnInThis() public boolean isPossibleToRespawnInThis(BlockState p_279289_) {
{ return false; } return false;
}
} }

View file

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

View file

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

View file

@ -9,6 +9,9 @@
*/ */
package dev.zontreck.engineerdecor.blocks; 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.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.sounds.SoundEvents; 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.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape; import net.minecraft.world.phys.shapes.VoxelShape;
import dev.zontreck.engineerdecor.ModContent; 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 javax.annotation.Nullable;
import java.util.HashMap; import java.util.HashMap;
@ -85,8 +85,9 @@ public class EdHorizontalSupportBlock extends StandardBlocks.WaterLoggable
{ return RenderTypeHint.CUTOUT; } { return RenderTypeHint.CUTOUT; }
@Override @Override
public boolean isPossibleToRespawnInThis() public boolean isPossibleToRespawnInThis(BlockState p_279289_) {
{ return false; } return false;
}
@Override @Override
public boolean isValidSpawn(BlockState state, BlockGetter world, BlockPos pos, SpawnPlacements.Type type, @Nullable EntityType<?> entityType) 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; 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.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.network.chat.Component; 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.minecraft.world.phys.shapes.VoxelShape;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; 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 javax.annotation.Nullable;
import java.util.List; 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 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_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)); 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)); protected static final VoxelShape EDLADDER_NORTH_AABB = Shapes.create(Auxiliaries.getRotatedAABB(EDLADDER_UNROTATED_AABB, Direction.NORTH, false));
private static boolean without_speed_boost_ = 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; without_speed_boost_ = without_speed_boost;
ModConfig.log("Config ladder: 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. // Player update event, forwarded from the main mod instance.
public static void onPlayerUpdateEvent(final Player player) public static void onPlayerUpdateEvent(final Player player) {
{ if ((without_speed_boost_) || (player.onGround()) || (!player.onClimbable()) || (player.isSteppingCarefully()) || (player.isSpectator()))
if((without_speed_boost_) || (player.isOnGround()) || (!player.onClimbable()) || (player.isSteppingCarefully()) || (player.isSpectator())) return; return;
double lvy = player.getLookAngle().y; double lvy = player.getLookAngle().y;
if (Math.abs(lvy) < 0.92) return; if (Math.abs(lvy) < 0.92) return;
final BlockPos pos = player.blockPosition(); final BlockPos pos = player.blockPosition();
final BlockState state = player.getLevel().getBlockState(pos); final BlockState state = player.level().getBlockState(pos);
final Block block = state.getBlock(); 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(); player.resetFallDistance();
if ((player.getDeltaMovement().y() < 0) == (player.getLookAngle().y < 0)) { if ((player.getDeltaMovement().y() < 0) == (player.getLookAngle().y < 0)) {
player.makeStuckInBlock(state, new Vec3(0.2, (lvy > 0) ? (3) : (6), 0.2)); 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; 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.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag; 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.item.context.BlockPlaceContext;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelReader; 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.Block;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockBehaviour; 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.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper; import net.minecraftforge.items.ItemHandlerHelper;
import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.registries.ForgeRegistries;
import dev.zontreck.engineerdecor.ModConfig;
import dev.zontreck.engineerdecor.ModContent;
import wile.engineersdecor.libmc.*;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.HashMap; import java.util.HashMap;
@ -62,8 +63,7 @@ import java.util.Map.Entry;
import java.util.UUID; import java.util.UUID;
public class EdMilker public class EdMilker {
{
public static final int BUCKET_SIZE = 1000; public static final int BUCKET_SIZE = 1000;
public static final int TICK_INTERVAL = 80; public static final int TICK_INTERVAL = 80;
public static final int PROCESSING_TICK_INTERVAL = 20; 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_ENERGY_CONSUMPTION = 0;
public static final int DEFAULT_MILKING_DELAY_PER_COW = 4000; public static final int DEFAULT_MILKING_DELAY_PER_COW = 4000;
private static final FluidStack NO_MILK_FLUID = new FluidStack(Fluids.WATER, 1000); 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 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 int energy_consumption_ = DEFAULT_ENERGY_CONSUMPTION;
private static long min_milking_delay_per_cow_ticks_ = DEFAULT_MILKING_DELAY_PER_COW; 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); 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); min_milking_delay_per_cow_ticks_ = Mth.clamp(min_milking_delay_per_cow, 1000, 24000);
{ {
@ -105,51 +103,54 @@ public class EdMilker
// Block // 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 FILLED = BooleanProperty.create("filled");
public static final BooleanProperty ACTIVE = BooleanProperty.create("active"); 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); super(config, builder, unrotatedAABBs);
cshapes.replaceAll((state, shape) -> Shapes.create(Auxiliaries.getPixeledAABB(0, 0, 0, 16, 24, 16))); cshapes.replaceAll((state, shape) -> Shapes.create(Auxiliaries.getPixeledAABB(0, 0, 0, 16, 24, 16)));
} }
@Override @Override
public boolean isBlockEntityTicking(Level world, BlockState state) public boolean isBlockEntityTicking(Level world, BlockState state) {
{ return true; } return true;
}
@Override @Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
{ super.createBlockStateDefinition(builder); builder.add(ACTIVE); builder.add(FILLED); } super.createBlockStateDefinition(builder);
builder.add(ACTIVE);
builder.add(FILLED);
}
@Override @Override
@Nullable @Nullable
public BlockState getStateForPlacement(BlockPlaceContext context) public BlockState getStateForPlacement(BlockPlaceContext context) {
{ return super.getStateForPlacement(context).setValue(FILLED, false).setValue(ACTIVE, false); } return super.getStateForPlacement(context).setValue(FILLED, false).setValue(ACTIVE, false);
}
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public boolean hasAnalogOutputSignal(BlockState state) public boolean hasAnalogOutputSignal(BlockState state) {
{ return true; } return true;
}
@Override @Override
@SuppressWarnings("deprecation") @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); MilkerTileEntity te = getTe(world, pos);
return (te == null) ? 0 : Mth.clamp((16 * te.fluid_level()) / TANK_CAPACITY, 0, 15); return (te == null) ? 0 : Mth.clamp((16 * te.fluid_level()) / TANK_CAPACITY, 0, 15);
} }
@Override @Override
public boolean shouldCheckWeakPower(BlockState state, LevelReader world, BlockPos pos, Direction side) public boolean shouldCheckWeakPower(BlockState state, SignalGetter level, BlockPos pos, Direction side) {
{ return false; } return false;
}
@Override @Override
@SuppressWarnings("deprecation") @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; if (world.isClientSide()) return InteractionResult.SUCCESS;
MilkerTileEntity te = getTe(world, pos); MilkerTileEntity te = getTe(world, pos);
if (te == null) return InteractionResult.FAIL; if (te == null) return InteractionResult.FAIL;
@ -186,8 +187,10 @@ public class EdMilker
} }
@Nullable @Nullable
private MilkerTileEntity getTe(Level world, BlockPos pos) private MilkerTileEntity getTe(Level world, BlockPos pos) {
{ final BlockEntity te=world.getBlockEntity(pos); return (!(te instanceof MilkerTileEntity)) ? (null) : ((MilkerTileEntity)te); } 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 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 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 int tick_timer_;
private UUID tracked_cow_ = null; private UUID tracked_cow_ = null;
private MilkingState state_ = MilkingState.IDLE; private MilkingState state_ = MilkingState.IDLE;
private int state_timeout_ = 0; private int state_timeout_ = 0;
private int state_timer_ = 0; private int state_timer_ = 0;
private BlockPos tracked_cow_original_position_ = null; 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); super(ModContent.getBlockEntityTypeOfBlock(state.getBlock()), pos, state);
tank_ = new Fluidics.Tank(TANK_CAPACITY, 0, BUCKET_SIZE, fs -> fs.isFluidEqual(milk_fluid_)); tank_ = new Fluidics.Tank(TANK_CAPACITY, 0, BUCKET_SIZE, fs -> fs.isFluidEqual(milk_fluid_));
fluid_handler_ = tank_.createOutputFluidHandler(); fluid_handler_ = tank_.createOutputFluidHandler();
@ -220,8 +221,11 @@ public class EdMilker
reset(); 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(); tank_.clear();
battery_.clear(); battery_.clear();
tick_timer_ = 0; tick_timer_ = 0;
@ -230,90 +234,91 @@ public class EdMilker
state_timeout_ = 0; state_timeout_ = 0;
} }
public CompoundTag destroy_getnbt() public CompoundTag destroy_getnbt() {
{
final UUID cowuid = tracked_cow_; final UUID cowuid = tracked_cow_;
CompoundTag nbt = new CompoundTag(); CompoundTag nbt = new CompoundTag();
writenbt(nbt, false); reset(); writenbt(nbt, false);
reset();
if (cowuid == null) return nbt; 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)); level.getEntitiesOfClass(Cow.class, new AABB(worldPosition).inflate(16, 16, 16), e -> e.getUUID().equals(cowuid)).forEach(e -> e.setNoAi(false));
return nbt; return nbt;
} }
public void readnbt(CompoundTag nbt, boolean update_packet) public void readnbt(CompoundTag nbt, boolean update_packet) {
{
battery_.load(nbt); battery_.load(nbt);
tank_.load(nbt); tank_.load(nbt);
} }
protected void writenbt(CompoundTag nbt, boolean update_packet) protected void writenbt(CompoundTag nbt, boolean update_packet) {
{
tank_.save(nbt); tank_.save(nbt);
if (!battery_.isEmpty()) battery_.save(nbt); if (!battery_.isEmpty()) battery_.save(nbt);
} }
private boolean has_milk_fluid() private boolean has_milk_fluid() {
{ return !(NO_MILK_FLUID.isFluidEqual(milk_fluid_)); } return !(NO_MILK_FLUID.isFluidEqual(milk_fluid_));
}
private IFluidHandler fluid_handler() private IFluidHandler fluid_handler() {
{ return fluid_handler_.orElse(null); } return fluid_handler_.orElse(null);
}
private int fluid_level() private int fluid_level() {
{ return tank_.getFluidAmount(); } return tank_.getFluidAmount();
}
private FluidStack drain(int amount) private FluidStack drain(int amount) {
{ return tank_.drain(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));
} }
// BlockEntity ------------------------------------------------------------------------------ // BlockEntity ------------------------------------------------------------------------------
@Override public void state_message(Player player) {
public void load(CompoundTag nbt) Component rf = (energy_consumption_ <= 0) ? (Component.empty()) : (Auxiliaries.localizable("block.engineersdecor.small_milking_machine.status.rf", battery_.getEnergyStored()));
{ super.load(nbt); readnbt(nbt, false); } Overlay.show(player, Auxiliaries.localizable("block.engineersdecor.small_milking_machine.status", tank_.getFluidAmount(), rf));
}
@Override @Override
protected void saveAdditional(CompoundTag nbt) public void load(CompoundTag nbt) {
{ super.saveAdditional(nbt); writenbt(nbt, false); } super.load(nbt);
readnbt(nbt, false);
}
@Override @Override
public void setRemoved() protected void saveAdditional(CompoundTag nbt) {
{ super.saveAdditional(nbt);
super.setRemoved(); writenbt(nbt, false);
energy_handler_.invalidate();
fluid_handler_.invalidate();
} }
// ICapabilityProvider --------------------------------------------------------------------------- // ICapabilityProvider ---------------------------------------------------------------------------
@Override @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.FLUID_HANDLER) && has_milk_fluid()) return fluid_handler_.cast();
if ((capability == ForgeCapabilities.ENERGY) && (energy_consumption_ > 0)) return energy_handler_.cast(); if ((capability == ForgeCapabilities.ENERGY) && (energy_consumption_ > 0)) return energy_handler_.cast();
return super.getCapability(capability, facing); 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 boolean fill_adjacent_inventory_item_containers(Direction block_facing) {
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)
{
// Check inventory existence, back to down is preferred, otherwise sort back into same inventory. // 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 src = Inventories.itemhandler(level, worldPosition.relative(block_facing), block_facing.getOpposite());
IItemHandler dst = Inventories.itemhandler(level, worldPosition.below(), Direction.UP); 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; if ((src == null) || (dst == null)) return false;
boolean dirty = false; boolean dirty = false;
while ((tank_.getFluidAmount() >= BUCKET_SIZE)) { while ((tank_.getFluidAmount() >= BUCKET_SIZE)) {
@ -332,8 +337,7 @@ public class EdMilker
return dirty; return dirty;
} }
private boolean fill_adjacent_tank() private boolean fill_adjacent_tank() {
{
if ((fluid_level() <= 0) || (!has_milk_fluid())) return false; if ((fluid_level() <= 0) || (!has_milk_fluid())) return false;
final FluidStack fs = new FluidStack(milk_fluid_, Math.max(fluid_level(), BUCKET_SIZE)); final FluidStack fs = new FluidStack(milk_fluid_, Math.max(fluid_level(), BUCKET_SIZE));
for (Direction dir : Direction.values()) { for (Direction dir : Direction.values()) {
@ -346,8 +350,7 @@ public class EdMilker
return false; return false;
} }
private void release_cow(Cow cow) private void release_cow(Cow cow) {
{
log("release cow"); log("release cow");
if (cow != null) { if (cow != null) {
cow.setNoAi(false); cow.setNoAi(false);
@ -362,8 +365,7 @@ public class EdMilker
tick_timer_ = TICK_INTERVAL; 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 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 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); 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 (e.getUUID().equals(tracked_cow_)) return true;
if ((tracked_cow_ != null) || e.isBaby() || e.isInLove() || e.isVehicle()) return false; if ((tracked_cow_ != null) || e.isBaby() || e.isInLove() || e.isVehicle()) return false;
if (!e.getNavigation().isDone()) 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; return true;
} }
); );
@ -386,10 +389,20 @@ public class EdMilker
cow = cows.get(level.random.nextInt(cows.size() - 1)); // pick one 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 ((state_ != MilkingState.IDLE) && ((state_timeout_ -= PROCESSING_TICK_INTERVAL) <= 0)) {
if((cow == null) || (!cow.isAlive())) { release_cow(cow); cow = null; } 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 (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; tick_timer_ = PROCESSING_TICK_INTERVAL;
state_timer_ -= PROCESSING_TICK_INTERVAL; state_timer_ -= PROCESSING_TICK_INTERVAL;
if (state_timer_ > 0) return false; if (state_timer_ > 0) return false;
@ -407,7 +420,7 @@ public class EdMilker
} }
return false; 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; return false;
tracked_cows_.put(cow.getId(), cow.getCommandSenderWorld().getGameTime()); tracked_cows_.put(cow.getId(), cow.getCommandSenderWorld().getGameTime());
tracked_cow_ = cow.getUUID(); tracked_cow_ = cow.getUUID();
@ -493,8 +506,7 @@ public class EdMilker
} }
@Override @Override
public void tick() public void tick() {
{
if ((level.isClientSide) || ((--tick_timer_ > 0))) return; if ((level.isClientSide) || ((--tick_timer_ > 0))) return;
tick_timer_ = TICK_INTERVAL; tick_timer_ = TICK_INTERVAL;
boolean dirty = false; boolean dirty = false;
@ -521,7 +533,8 @@ public class EdMilker
// Adjacent inventory update, only done just after milking to prevent waste of server cpu. // Adjacent inventory update, only done just after milking to prevent waste of server cpu.
if ((!dirty) && (fluid_level() > 0)) { if ((!dirty) && (fluid_level() > 0)) {
log("Try item transfer"); 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 // State update
@ -529,14 +542,11 @@ public class EdMilker
if (block_state != new_state) level.setBlock(worldPosition, new_state, 1 | 2 | 16); if (block_state != new_state) level.setBlock(worldPosition, new_state, 1 | 2 | 16);
if (dirty) setChanged(); if (dirty) setChanged();
} }
private enum MilkingState {IDLE, PICKED, COMING, POSITIONING, MILKING, LEAVING, WAITING}
} }
public static class SingleMoveGoal extends MoveToBlockGoal 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);
private static final HashMap<Integer, SingleMoveGoal> tracked_entities_ = new HashMap<>(); private static final HashMap<Integer, SingleMoveGoal> tracked_entities_ = new HashMap<>();
private static final int motion_timeout = 20 * 20; private static final int motion_timeout = 20 * 20;
private boolean aborted_; private boolean aborted_;
@ -546,9 +556,7 @@ public class EdMilker
private TargetPositionInValidCheck abort_condition_; private TargetPositionInValidCheck abort_condition_;
private StrollEvent on_target_position_reached_; private StrollEvent on_target_position_reached_;
private StrollEvent on_aborted_; 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); super(creature, speed, 32, 32);
abort_condition_ = abort_condition; abort_condition_ = abort_condition;
on_target_position_reached_ = on_position_reached; on_target_position_reached_ = on_position_reached;
@ -561,11 +569,14 @@ public class EdMilker
target_pos_ = pos; target_pos_ = pos;
} }
public static void startFor(PathfinderMob entity, BlockPos target_pos, int priority, double speed, TargetPositionInValidCheck abort_condition) private static void log(String s) {
{ startFor(entity, new Vec3(target_pos.getX(),target_pos.getY(),target_pos.getZ()), priority, speed, abort_condition, null, null); } } // 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_) { synchronized (tracked_entities_) {
SingleMoveGoal goal = tracked_entities_.getOrDefault(entity.getId(), null); SingleMoveGoal goal = tracked_entities_.getOrDefault(entity.getId(), null);
if (goal != null) { if (goal != null) {
@ -580,13 +591,13 @@ public class EdMilker
} }
} }
public static boolean isActiveFor(PathfinderMob entity) public static boolean isActiveFor(PathfinderMob entity) {
{ return (entity != null) && (entity.goalSelector.getRunningGoals().anyMatch( return (entity != null) && (entity.goalSelector.getRunningGoals().anyMatch(
g -> ((g.getGoal()) instanceof SingleMoveGoal) && (!((SingleMoveGoal) (g.getGoal())).aborted()) 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() + ")"); log("::abort(" + entity.getId() + ")");
if (entity.isAlive()) { if (entity.isAlive()) {
entity.goalSelector.getRunningGoals().filter(g -> (g.getGoal()) instanceof SingleMoveGoal).forEach(g -> ((SingleMoveGoal) g.getGoal()).abort()); 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() public Vec3 getTargetPosition() {
{ return target_pos_; } return target_pos_;
}
public PathfinderMob getCreature() public PathfinderMob getCreature() {
{ return mob; } return mob;
}
public synchronized void abort() public synchronized void abort() {
{ aborted_ = true; } aborted_ = true;
}
public synchronized boolean aborted() public synchronized boolean aborted() {
{ return 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; abort_condition_ = abort_condition;
on_target_position_reached_ = on_position_reached; on_target_position_reached_ = on_position_reached;
on_aborted_ = on_aborted; on_aborted_ = on_aborted;
@ -626,26 +640,31 @@ public class EdMilker
} }
@Override @Override
public void stop() public void stop() {
{ nextStartTick = 0; tryTicks = 0; } nextStartTick = 0;
tryTicks = 0;
}
@Override @Override
public double acceptedDistance() public double acceptedDistance() {
{ return 0.7; } return 0.7;
}
@Override @Override
public boolean shouldRecalculatePath() public boolean shouldRecalculatePath() {
{ return (!aborted()) && (tryTicks & 0x7) == 0; } return (!aborted()) && (tryTicks & 0x7) == 0;
}
@Override @Override
public boolean canUse() public boolean canUse() {
{
if (aborted_) { 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; was_aborted_ = true;
return false; return false;
} else if(!isValidTarget(mob.level, blockPos)) { } else if (!isValidTarget(mob.level(), blockPos)) {
synchronized(this) { aborted_ = true; } synchronized (this) {
aborted_ = true;
}
return false; return false;
} else if (--nextStartTick > 0) { } else if (--nextStartTick > 0) {
return false; return false;
@ -656,8 +675,7 @@ public class EdMilker
} }
@Override @Override
public void start() public void start() {
{
tryTicks = 0; tryTicks = 0;
if (!mob.getNavigation().moveTo(target_pos_.x(), target_pos_.y(), target_pos_.z(), this.speedModifier)) { if (!mob.getNavigation().moveTo(target_pos_.x(), target_pos_.y(), target_pos_.z(), this.speedModifier)) {
abort(); abort();
@ -667,8 +685,7 @@ public class EdMilker
} }
} }
public boolean canContinueToUse() public boolean canContinueToUse() {
{
if (aborted()) { if (aborted()) {
log("shouldContinueExecuting() -> already aborted"); log("shouldContinueExecuting() -> already aborted");
return false; return false;
@ -684,7 +701,7 @@ public class EdMilker
log("shouldContinueExecuting() -> abort, timeout"); log("shouldContinueExecuting() -> abort, timeout");
abort(); abort();
return false; return false;
} else if(!isValidTarget(mob.level, blockPos)) { } else if (!isValidTarget(mob.level(), blockPos)) {
log("shouldContinueExecuting() -> abort, !shouldMoveTo()"); log("shouldContinueExecuting() -> abort, !shouldMoveTo()");
abort(); abort();
return false; return false;
@ -695,8 +712,7 @@ public class EdMilker
} }
@Override @Override
protected boolean isValidTarget(LevelReader world, BlockPos pos) protected boolean isValidTarget(LevelReader world, BlockPos pos) {
{
if (abort_condition_.test(this, world, pos)) { if (abort_condition_.test(this, world, pos)) {
log("shouldMoveTo() -> abort_condition"); log("shouldMoveTo() -> abort_condition");
return false; return false;
@ -706,9 +722,8 @@ public class EdMilker
} }
@Override @Override
public void tick() public void tick() {
{ final BlockPos testpos = new BlockPos((int) target_pos_.x(), (int) mob.position().y(), (int) target_pos_.z());
final BlockPos testpos = new BlockPos(target_pos_.x(), mob.position().y(), target_pos_.z());
if (!testpos.closerToCenterThan(mob.position(), acceptedDistance())) { if (!testpos.closerToCenterThan(mob.position(), acceptedDistance())) {
if ((++tryTicks > motion_timeout)) { if ((++tryTicks > motion_timeout)) {
log("tick() -> abort, timeoutCounter"); log("tick() -> abort, timeoutCounter");
@ -723,8 +738,19 @@ public class EdMilker
log("tick() -> abort, in position)"); log("tick() -> abort, in position)");
in_position_ = true; in_position_ = true;
abort(); 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; 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.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.core.particles.ParticleOptions; 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.item.context.BlockPlaceContext;
import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level; 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.Block;
import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.entity.BlockEntity; 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.FluidStack;
import net.minecraftforge.fluids.capability.IFluidHandler; import net.minecraftforge.fluids.capability.IFluidHandler;
import net.minecraftforge.items.IItemHandler; 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 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 class EdMineralSmelter {
{ public static void on_config(int consumption, int heatup_per_second) {
public static void on_config(int consumption, int heatup_per_second) MineralSmelterTileEntity.on_config(consumption, heatup_per_second);
{ MineralSmelterTileEntity.on_config(consumption, heatup_per_second); } }
//-------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------
// Block // 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 int PHASE_MAX = 3;
public static final IntegerProperty PHASE = IntegerProperty.create("phase", 0, PHASE_MAX); public static final IntegerProperty PHASE = IntegerProperty.create("phase", 0, PHASE_MAX);
public MineralSmelterBlock(long config, BlockBehaviour.Properties builder, final AABB unrotatedAABB) public MineralSmelterBlock(long config, BlockBehaviour.Properties builder, final AABB unrotatedAABB) {
{ super(config, builder, unrotatedAABB); } super(config, builder, unrotatedAABB);
}
@Override @Override
public boolean isBlockEntityTicking(Level world, BlockState state) public boolean isBlockEntityTicking(Level world, BlockState state) {
{ return true; } return true;
}
@Override @Override
public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) {
{ return Shapes.block(); } return Shapes.block();
}
@Override @Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
{ super.createBlockStateDefinition(builder); builder.add(PHASE); } super.createBlockStateDefinition(builder);
builder.add(PHASE);
}
@Override @Override
@Nullable @Nullable
public BlockState getStateForPlacement(BlockPlaceContext context) public BlockState getStateForPlacement(BlockPlaceContext context) {
{ return super.getStateForPlacement(context).setValue(PHASE, 0); } return super.getStateForPlacement(context).setValue(PHASE, 0);
}
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public boolean hasAnalogOutputSignal(BlockState state) public boolean hasAnalogOutputSignal(BlockState state) {
{ return true; } return true;
}
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public int getAnalogOutputSignal(BlockState state, Level world, BlockPos pos) public int getAnalogOutputSignal(BlockState state, Level world, BlockPos pos) {
{ return Mth.clamp((state.getValue(PHASE)*5), 0, 15); } return Mth.clamp((state.getValue(PHASE) * 5), 0, 15);
}
@Override @Override
public boolean shouldCheckWeakPower(BlockState state, LevelReader world, BlockPos pos, Direction side) public boolean shouldCheckWeakPower(BlockState state, SignalGetter level, BlockPos pos, Direction side) {
{ return false; } return false;
}
@Override @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 @Override
public boolean hasDynamicDropList() public boolean hasDynamicDropList() {
{ return true; } return true;
}
@Override @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<>(); final List<ItemStack> stacks = new ArrayList<>();
if (world.isClientSide) return stacks; if (world.isClientSide) return stacks;
if (!(te instanceof MineralSmelterTileEntity)) return stacks; if (!(te instanceof MineralSmelterTileEntity)) return stacks;
@ -132,8 +138,7 @@ public class EdMineralSmelter
@Override @Override
@SuppressWarnings("deprecation") @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 (player.isShiftKeyDown()) return InteractionResult.PASS;
if (world.isClientSide()) return InteractionResult.SUCCESS; if (world.isClientSide()) return InteractionResult.SUCCESS;
MineralSmelterTileEntity te = getTe(world, pos); MineralSmelterTileEntity te = getTe(world, pos);
@ -141,7 +146,7 @@ public class EdMineralSmelter
final ItemStack stack = player.getItemInHand(hand); final ItemStack stack = player.getItemInHand(hand);
boolean dirty = false; boolean dirty = false;
if (te.accepts_lava_container(stack)) { 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 (te.bucket_extraction_possible()) {
if (stack.getCount() > 1) { if (stack.getCount() > 1) {
int target_stack_index = -1; int target_stack_index = -1;
@ -184,8 +189,7 @@ public class EdMineralSmelter
@Override @Override
@OnlyIn(Dist.CLIENT) @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; if (state.getBlock() != this) return;
ParticleOptions particle = ParticleTypes.SMOKE; ParticleOptions particle = ParticleTypes.SMOKE;
switch (state.getValue(PHASE)) { switch (state.getValue(PHASE)) {
@ -211,16 +215,17 @@ public class EdMineralSmelter
} }
@Nullable @Nullable
private MineralSmelterTileEntity getTe(Level world, BlockPos pos) private MineralSmelterTileEntity getTe(Level world, BlockPos pos) {
{ final BlockEntity te=world.getBlockEntity(pos); return (!(te instanceof MineralSmelterTileEntity)) ? (null) : ((MineralSmelterTileEntity)te); } final BlockEntity te = world.getBlockEntity(pos);
return (!(te instanceof MineralSmelterTileEntity)) ? (null) : ((MineralSmelterTileEntity) te);
}
} }
//-------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------
// Tile entity // 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 NUM_OF_SLOTS = 2;
public static final int TICK_INTERVAL = 20; public static final int TICK_INTERVAL = 20;
public static final int MAX_FLUID_LEVEL = 2000; 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 energy_consumption = DEFAULT_ENERGY_CONSUMPTION;
private static int heatup_rate = DEFAULT_HEATUP_RATE; private static int heatup_rate = DEFAULT_HEATUP_RATE;
private static int cooldown_rate = 1; private static int cooldown_rate = 1;
private int tick_timer_;
private int progress_; static {
private boolean force_block_update_; accepted_lava_contrainers.add(Items.BUCKET);
}
private final RfEnergy.Battery battery_ = new RfEnergy.Battery(MAX_ENERGY_BUFFER, MAX_ENERGY_TRANSFER, 0); private final RfEnergy.Battery battery_ = new RfEnergy.Battery(MAX_ENERGY_BUFFER, MAX_ENERGY_TRANSFER, 0);
private final LazyOptional<IEnergyStorage> energy_handler_ = battery_.createEnergyHandler(); 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 LazyOptional<? extends IFluidHandler> fluid_handler_ = tank_.createOutputFluidHandler();
private final Inventories.StorageInventory main_inventory_; private final Inventories.StorageInventory main_inventory_;
private final LazyOptional<? extends IItemHandler> item_handler_; private final LazyOptional<? extends IItemHandler> item_handler_;
private int tick_timer_;
private int progress_;
private boolean force_block_update_;
static { public MineralSmelterTileEntity(BlockPos pos, BlockState state) {
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)
{
super(ModContent.getBlockEntityTypeOfBlock(state.getBlock()), pos, state); super(ModContent.getBlockEntityTypeOfBlock(state.getBlock()), pos, state);
main_inventory_ = (new Inventories.StorageInventory(this, NUM_OF_SLOTS, 1)).setStackLimit(1); main_inventory_ = (new Inventories.StorageInventory(this, NUM_OF_SLOTS, 1)).setStackLimit(1);
item_handler_ = Inventories.MappedItemHandler.createGenericHandler( item_handler_ = Inventories.MappedItemHandler.createGenericHandler(
main_inventory_, main_inventory_,
(index, stack) -> ((index == 1) && (phase() != PHASE_LAVA)), (index, stack) -> ((index == 1) && (phase() != PHASE_LAVA)),
(index, stack) -> ((index == 0) && (progress_ == 0) && accepts_input(stack)), (index, stack) -> ((index == 0) && (progress_ == 0) && accepts_input(stack)),
(index,stack)->{}, (index, stack) -> {
(index,stack)->{ if(index!=0) reset_process(); } },
(index, stack) -> {
if (index != 0) reset_process();
}
); );
} }
public int progress() public static void on_config(int consumption, int heatup_per_second) {
{ return progress_; } 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_ >= 100) return PHASE_LAVA;
if (progress_ >= 90) return PHASE_MAGMABLOCK; if (progress_ >= 90) return PHASE_MAGMABLOCK;
if (progress_ >= 5) return PHASE_HOT; if (progress_ >= 5) return PHASE_HOT;
return PHASE_WARMUP; return PHASE_WARMUP;
} }
public boolean bucket_extraction_possible() public boolean bucket_extraction_possible() {
{ return tank_.getFluidAmount() >= MAX_BUCKET_EXTRACT_FLUID_LEVEL; } return tank_.getFluidAmount() >= MAX_BUCKET_EXTRACT_FLUID_LEVEL;
}
public int comparator_signal() public int comparator_signal() {
{ return phase() * 5; } return phase() * 5;
}
private boolean accepts_lava_container(ItemStack stack) private boolean accepts_lava_container(ItemStack stack) {
{ return accepted_lava_contrainers.contains(stack.getItem()); } return accepted_lava_contrainers.contains(stack.getItem());
}
private boolean accepts_input(ItemStack stack) private boolean accepts_input(ItemStack stack) {
{
if (!main_inventory_.isEmpty()) { if (!main_inventory_.isEmpty()) {
return false; return false;
} else if (bucket_extraction_possible()) { } 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 (stack.isEmpty() || (!accepts_input(stack))) return false;
if (!simulate) { if (!simulate) {
final ItemStack st = stack.copy(); final ItemStack st = stack.copy();
@ -322,16 +329,14 @@ public class EdMineralSmelter
return true; return true;
} }
public ItemStack extract(boolean simulate) public ItemStack extract(boolean simulate) {
{
final ItemStack stack = main_inventory_.getItem(1).copy(); final ItemStack stack = main_inventory_.getItem(1).copy();
if (stack.isEmpty()) return ItemStack.EMPTY; if (stack.isEmpty()) return ItemStack.EMPTY;
if (!simulate) reset_process(); if (!simulate) reset_process();
return stack; return stack;
} }
protected void reset_process() protected void reset_process() {
{
main_inventory_.setItem(0, ItemStack.EMPTY); main_inventory_.setItem(0, ItemStack.EMPTY);
main_inventory_.setItem(1, ItemStack.EMPTY); main_inventory_.setItem(1, ItemStack.EMPTY);
tank_.clear(); tank_.clear();
@ -340,16 +345,14 @@ public class EdMineralSmelter
progress_ = 0; progress_ = 0;
} }
public void readnbt(CompoundTag nbt) public void readnbt(CompoundTag nbt) {
{
main_inventory_.load(nbt); main_inventory_.load(nbt);
battery_.load(nbt); battery_.load(nbt);
tank_.load(nbt); tank_.load(nbt);
progress_ = nbt.getInt("progress"); progress_ = nbt.getInt("progress");
} }
protected void writenbt(CompoundTag nbt) protected void writenbt(CompoundTag nbt) {
{
main_inventory_.save(nbt); main_inventory_.save(nbt);
battery_.save(nbt); battery_.save(nbt);
tank_.save(nbt); tank_.save(nbt);
@ -359,16 +362,19 @@ public class EdMineralSmelter
// BlockEntity ------------------------------------------------------------------------------ // BlockEntity ------------------------------------------------------------------------------
@Override @Override
public void load(CompoundTag nbt) public void load(CompoundTag nbt) {
{ super.load(nbt); readnbt(nbt); } super.load(nbt);
readnbt(nbt);
}
@Override @Override
protected void saveAdditional(CompoundTag nbt) protected void saveAdditional(CompoundTag nbt) {
{ super.saveAdditional(nbt); writenbt(nbt); } super.saveAdditional(nbt);
writenbt(nbt);
}
@Override @Override
public void setRemoved() public void setRemoved() {
{
super.setRemoved(); super.setRemoved();
energy_handler_.invalidate(); energy_handler_.invalidate();
fluid_handler_.invalidate(); fluid_handler_.invalidate();
@ -378,8 +384,7 @@ public class EdMineralSmelter
// Capability export ---------------------------------------------------------------------------- // Capability export ----------------------------------------------------------------------------
@Override @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.ITEM_HANDLER) return item_handler_.cast();
if (capability == ForgeCapabilities.FLUID_HANDLER) return fluid_handler_.cast(); if (capability == ForgeCapabilities.FLUID_HANDLER) return fluid_handler_.cast();
if (capability == ForgeCapabilities.ENERGY) return energy_handler_.cast(); if (capability == ForgeCapabilities.ENERGY) return energy_handler_.cast();
@ -389,8 +394,7 @@ public class EdMineralSmelter
// ITickable ------------------------------------------------------------------------------------ // ITickable ------------------------------------------------------------------------------------
@Override @Override
public void tick() public void tick() {
{
if (--tick_timer_ > 0) return; if (--tick_timer_ > 0) return;
tick_timer_ = TICK_INTERVAL; tick_timer_ = TICK_INTERVAL;
BlockState state = level.getBlockState(worldPosition); BlockState state = level.getBlockState(worldPosition);
@ -414,8 +418,8 @@ public class EdMineralSmelter
final int new_phase = phase(); final int new_phase = phase();
if (accepts_lava_container(istack)) { if (accepts_lava_container(istack)) {
// That stays in the slot until its extracted or somone takes it out. // That stays in the slot until its extracted or somone takes it out.
if(istack.sameItem(BUCKET_STACK)) { if (istack.is(BUCKET_STACK.getItem())) {
if(!main_inventory_.getItem(1).sameItem(LAVA_BUCKET_STACK)) { if (!main_inventory_.getItem(1).is(LAVA_BUCKET_STACK.getItem())) {
if (bucket_extraction_possible()) { if (bucket_extraction_possible()) {
reset_process(); reset_process();
main_inventory_.setItem(1, LAVA_BUCKET_STACK); main_inventory_.setItem(1, LAVA_BUCKET_STACK);
@ -463,7 +467,7 @@ public class EdMineralSmelter
dirty = true; dirty = true;
} }
case PHASE_HOT -> { case PHASE_HOT -> {
if(istack.sameItem(MAGMA_STACK)) { if (istack.is(MAGMA_STACK.getItem())) {
main_inventory_.setItem(1, new ItemStack(Blocks.OBSIDIAN)); main_inventory_.setItem(1, new ItemStack(Blocks.OBSIDIAN));
} else { } else {
main_inventory_.setItem(1, new ItemStack(Blocks.COBBLESTONE)); main_inventory_.setItem(1, new ItemStack(Blocks.COBBLESTONE));

View file

@ -9,6 +9,11 @@
*/ */
package dev.zontreck.engineerdecor.blocks; 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.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.util.Mth; 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.BlockGetter;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor; 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.Block;
import net.minecraft.world.level.block.Rotation; import net.minecraft.world.level.block.Rotation;
import net.minecraft.world.level.block.entity.BlockEntity; 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.common.util.LazyOptional;
import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.IFluidHandler; 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.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
public class EdPipeValve public class EdPipeValve {
{
public static final int CFG_CHECK_VALVE = 0x1; public static final int CFG_CHECK_VALVE = 0x1;
public static final int CFG_ANALOG_VALVE = 0x2; public static final int CFG_ANALOG_VALVE = 0x2;
public static final int CFG_REDSTONE_CONTROLLED_VALVE = 0x4; 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.fluid_maxflow_mb = Mth.clamp(container_size_decl, 1, 10000);
PipeValveTileEntity.redstone_flow_slope_mb = Mth.clamp(redstone_slope, 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."); 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 // 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_N = BooleanProperty.create("rs_n");
public static final BooleanProperty RS_CN_S = BooleanProperty.create("rs_s"); public static final BooleanProperty RS_CN_S = BooleanProperty.create("rs_s");
public static final BooleanProperty RS_CN_E = BooleanProperty.create("rs_e"); 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 static final BooleanProperty RS_CN_D = BooleanProperty.create("rs_d");
public final int valve_config; public final int valve_config;
public PipeValveBlock(long config, int valve_config, BlockBehaviour.Properties builder, final AABB[] unrotatedAABB) public PipeValveBlock(long config, int valve_config, BlockBehaviour.Properties builder, final AABB[] unrotatedAABB) {
{ super(config, builder, unrotatedAABB); this.valve_config = valve_config; } super(config, builder, unrotatedAABB);
this.valve_config = valve_config;
}
@Override @Override
@Nullable @Nullable
public BlockEntity newBlockEntity(BlockPos pos, BlockState state) public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
{
final BlockEntityType<?> tet = ModContent.getBlockEntityTypeOfBlock("straight_pipe_valve"); final BlockEntityType<?> tet = ModContent.getBlockEntityTypeOfBlock("straight_pipe_valve");
return (tet == null) ? null : tet.create(pos, state); return (tet == null) ? null : tet.create(pos, state);
} }
@Override @Override
public boolean isBlockEntityTicking(Level world, BlockState state) public boolean isBlockEntityTicking(Level world, BlockState state) {
{ return false; } return false;
}
@Override @Override
public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) {
{ return Shapes.block(); } return Shapes.block();
}
@Override @Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) 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); } super.createBlockStateDefinition(builder);
builder.add(RS_CN_N, RS_CN_S, RS_CN_E, RS_CN_W, RS_CN_U, RS_CN_D);
}
@Override @Override
@Nullable @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) 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); .setValue(RS_CN_W, false).setValue(RS_CN_U, false).setValue(RS_CN_D, false);
} }
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public BlockState updateShape(BlockState state, Direction facing, BlockState facingState, LevelAccessor world, BlockPos pos, BlockPos facingPos) public BlockState updateShape(BlockState state, Direction facing, BlockState facingState, LevelAccessor world, BlockPos pos, BlockPos facingPos) {
{ return get_rsconnector_state(state, world, pos, null); } return get_rsconnector_state(state, world, pos, null);
}
@Override @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.updateNeighborsAt(pos,this); } world.updateNeighborsAt(pos, this);
}
@Override @Override
public BlockState rotate(BlockState state, LevelAccessor world, BlockPos pos, Rotation direction) public BlockState rotate(BlockState state, LevelAccessor world, BlockPos pos, Rotation direction) {
{ return get_rsconnector_state(state, world, pos, null); } // don't rotate at all return get_rsconnector_state(state, world, pos, null);
} // don't rotate at all
@Override @Override
public boolean hasSignalConnector(BlockState state, BlockGetter world, BlockPos pos, @Nullable Direction side) public boolean hasSignalConnector(BlockState state, BlockGetter world, BlockPos pos, @Nullable Direction side) {
{ return (side!=null) && (side!=state.getValue(FACING)) && (side!=state.getValue(FACING).getOpposite()); } return (side != null) && (side != state.getValue(FACING)) && (side != state.getValue(FACING).getOpposite());
}
@Override @Override
public boolean shouldCheckWeakPower(BlockState state, LevelReader world, BlockPos pos, Direction side) public boolean shouldCheckWeakPower(BlockState state, SignalGetter level, BlockPos pos, Direction side) {
{ return false; } 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; }
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public int getSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side) // public boolean canConnectRedstone(BlockState state, BlockGetter world, BlockPos pos, @Nullable Direction side) { return true; }
{ return 0; } public boolean isSignalSource(BlockState p_60571_) {
return true;
}
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public int getDirectSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side) public int getSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side) {
{ return 0; } 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; if ((valve_config & (CFG_REDSTONE_CONTROLLED_VALVE)) == 0) return state;
Direction.Axis bfa = state.getValue(FACING).getAxis(); Direction.Axis bfa = state.getValue(FACING).getAxis();
for (Direction f : Direction.values()) { for (Direction f : Direction.values()) {
boolean cn = (f.getAxis() != bfa); boolean cn = (f.getAxis() != bfa);
if (cn) { if (cn) {
BlockPos nbp = pos.relative(f); 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); 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) { switch (f) {
case NORTH -> state = state.setValue(RS_CN_N, cn); case NORTH -> state = state.setValue(RS_CN_N, cn);
@ -169,25 +180,29 @@ public class EdPipeValve
// Tile entity // 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 fluid_maxflow_mb = 1000;
protected static int redstone_flow_slope_mb = 1000 / 15; protected static int redstone_flow_slope_mb = 1000 / 15;
private final Direction block_facing_ = null; 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 boolean filling_ = false;
private int valve_config_; private int valve_config_;
public PipeValveTileEntity(BlockPos pos, BlockState state) public PipeValveTileEntity(BlockPos pos, BlockState state) {
{ super(ModContent.getBlockEntityTypeOfBlock("straight_pipe_valve"), pos, state); } super(ModContent.getBlockEntityTypeOfBlock("straight_pipe_valve"), pos, state);
}
private Direction block_facing() // BlockEntity -----------------------------------------------------------------------------
{
private Direction block_facing() {
BlockState st = getLevel().getBlockState(getBlockPos()); BlockState st = getLevel().getBlockState(getBlockPos());
return (st.getBlock() instanceof PipeValveBlock) ? st.getValue(PipeValveBlock.FACING) : Direction.NORTH; return (st.getBlock() instanceof PipeValveBlock) ? st.getValue(PipeValveBlock.FACING) : Direction.NORTH;
} }
private long valve_config() // ICapabilityProvider --------------------------------------------------------------------
{
private long valve_config() {
if (valve_config_ <= 0) { if (valve_config_ <= 0) {
final Block block = getLevel().getBlockState(getBlockPos()).getBlock(); final Block block = getLevel().getBlockState(getBlockPos()).getBlock();
if (block instanceof PipeValveBlock) valve_config_ = ((PipeValveBlock) block).valve_config; if (block instanceof PipeValveBlock) valve_config_ = ((PipeValveBlock) block).valve_config;
@ -195,24 +210,15 @@ public class EdPipeValve
return valve_config_; return valve_config_;
} }
// BlockEntity -----------------------------------------------------------------------------
@Override @Override
public void setRemoved() public void setRemoved() {
{
super.setRemoved(); super.setRemoved();
back_flow_handler_.invalidate(); back_flow_handler_.invalidate();
fluid_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 @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) { if (capability == ForgeCapabilities.FLUID_HANDLER) {
Direction bf = block_facing(); Direction bf = block_facing();
if (facing == bf) return back_flow_handler_.cast(); if (facing == bf) return back_flow_handler_.cast();
@ -225,8 +231,7 @@ public class EdPipeValve
// IFluidHandlers // IFluidHandlers
@Nullable @Nullable
private IFluidHandler forward_fluid_handler() private IFluidHandler forward_fluid_handler() {
{
final BlockEntity te = level.getBlockEntity(worldPosition.relative(block_facing())); final BlockEntity te = level.getBlockEntity(worldPosition.relative(block_facing()));
if (te == null) return null; if (te == null) return null;
return te.getCapability(ForgeCapabilities.FLUID_HANDLER, block_facing().getOpposite()).orElse(null); return te.getCapability(ForgeCapabilities.FLUID_HANDLER, block_facing().getOpposite()).orElse(null);
@ -234,19 +239,45 @@ public class EdPipeValve
// Forward flow handler -- // Forward flow handler --
private static class MainFlowHandler implements IFluidHandler private static class MainFlowHandler implements IFluidHandler {
{
private final PipeValveTileEntity te; 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; if (te.filling_) return 0;
final IFluidHandler fh = te.forward_fluid_handler(); final IFluidHandler fh = te.forward_fluid_handler();
if (fh == null) return 0; if (fh == null) return 0;
@ -254,7 +285,8 @@ public class EdPipeValve
if ((te.valve_config() & CFG_REDSTONE_CONTROLLED_VALVE) != 0) { if ((te.valve_config() & CFG_REDSTONE_CONTROLLED_VALVE) != 0) {
int rs = te.level.getBestNeighborSignal(te.worldPosition); int rs = te.level.getBestNeighborSignal(te.worldPosition);
if (rs <= 0) return 0; 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); if (res.getAmount() > fluid_maxflow_mb) res.setAmount(fluid_maxflow_mb);
te.filling_ = true; te.filling_ = true;
@ -266,15 +298,41 @@ public class EdPipeValve
// Back flow prevention handler -- // Back flow prevention handler --
private static class BackFlowHandler implements IFluidHandler private static class BackFlowHandler implements IFluidHandler {
{ @Override
@Override public int getTanks() { return 1; } public int getTanks() {
@Override public FluidStack getFluidInTank(int tank) { return FluidStack.EMPTY; } return 1;
@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
@Override public FluidStack drain(FluidStack resource, FluidAction action) { return FluidStack.EMPTY; } public FluidStack getFluidInTank(int tank) {
@Override public FluidStack drain(int maxDrain, FluidAction action) { return FluidStack.EMPTY; } 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; package dev.zontreck.engineerdecor.blocks;
import com.mojang.blaze3d.vertex.PoseStack; import dev.zontreck.engineerdecor.ModContent;
import dev.zontreck.engineerdecor.libmc.*; import dev.zontreck.libzontreck.edlibmc.*;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag; 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.item.context.UseOnContext;
import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level; 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.Block;
import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.SoundType; 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.common.util.LazyOptional;
import net.minecraftforge.fluids.IFluidBlock; import net.minecraftforge.fluids.IFluidBlock;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
import dev.zontreck.engineerdecor.ModContent;
import wile.engineersdecor.libmc.*;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
@ -63,45 +62,48 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
public class EdPlacer public class EdPlacer {
{ public static void on_config() {
public static void on_config() }
{}
//-------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------
// Block // Block
//-------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------
public static class PlacerBlock extends StandardBlocks.Directed implements StandardEntityBlocks.IStandardEntityBlock<PlacerTileEntity> public static class PlacerBlock extends StandardBlocks.Directed implements StandardEntityBlocks.IStandardEntityBlock<PlacerTileEntity> {
{ public PlacerBlock(long config, BlockBehaviour.Properties builder, final AABB[] unrotatedAABB) {
public PlacerBlock(long config, BlockBehaviour.Properties builder, final AABB[] unrotatedAABB) super(config, builder, unrotatedAABB);
{ super(config, builder, unrotatedAABB); } }
@Override @Override
public boolean isBlockEntityTicking(Level world, BlockState state) public boolean isBlockEntityTicking(Level world, BlockState state) {
{ return true; } return true;
}
@Override @Override
public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) {
{ return Shapes.block(); } return Shapes.block();
}
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public boolean hasAnalogOutputSignal(BlockState state) public boolean hasAnalogOutputSignal(BlockState state) {
{ return true; } return true;
}
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public int getAnalogOutputSignal(BlockState blockState, Level world, BlockPos pos) public int getAnalogOutputSignal(BlockState blockState, Level world, BlockPos pos) {
{ return (world.getBlockEntity(pos) instanceof EdPlacer.PlacerTileEntity te) ? RsSignals.fromContainer(te.inventory_) : 0; } return (world.getBlockEntity(pos) instanceof EdPlacer.PlacerTileEntity te) ? RsSignals.fromContainer(te.inventory_) : 0;
}
@Override @Override
public boolean shouldCheckWeakPower(BlockState state, LevelReader world, BlockPos pos, Direction side) public boolean shouldCheckWeakPower(BlockState state, SignalGetter level, BlockPos pos, Direction side) {
{ return false; } return false;
}
@Override @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 (world.isClientSide) return;
if ((!stack.hasTag()) || (!stack.getTag().contains("tedata"))) return; if ((!stack.hasTag()) || (!stack.getTag().contains("tedata"))) return;
CompoundTag te_nbt = stack.getTag().getCompound("tedata"); CompoundTag te_nbt = stack.getTag().getCompound("tedata");
@ -113,12 +115,12 @@ public class EdPlacer
} }
@Override @Override
public boolean hasDynamicDropList() public boolean hasDynamicDropList() {
{ return true; } return true;
}
@Override @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<>(); final List<ItemStack> stacks = new ArrayList<>();
if (world.isClientSide) return stacks; if (world.isClientSide) return stacks;
if (!(te instanceof PlacerTileEntity)) return stacks; if (!(te instanceof PlacerTileEntity)) return stacks;
@ -142,13 +144,13 @@ public class EdPlacer
@Override @Override
@SuppressWarnings("deprecation") @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) {
{ return useOpenGui(state, world, pos, player); } return useOpenGui(state, world, pos, player);
}
@Override @Override
@SuppressWarnings("deprecation") @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; if (!(world instanceof Level) || (world.isClientSide)) return;
BlockEntity te = world.getBlockEntity(pos); BlockEntity te = world.getBlockEntity(pos);
if (!(te instanceof PlacerTileEntity)) return; if (!(te instanceof PlacerTileEntity)) return;
@ -157,26 +159,28 @@ public class EdPlacer
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public boolean isSignalSource(BlockState state) public boolean isSignalSource(BlockState state) {
{ return true; } return true;
}
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public int getSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side) public int getSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side) {
{ return 0; } return 0;
}
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public int getDirectSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side) public int getDirectSignal(BlockState blockState, BlockGetter blockAccess, BlockPos pos, Direction side) {
{ return 0; } return 0;
}
} }
//-------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------
// Tile entity // 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 TICK_INTERVAL = 40;
public static final int NUM_OF_SLOTS = 18; public static final int NUM_OF_SLOTS = 18;
public static final int NUM_OF_FIELDS = 3; 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_INVERTED = 0x01;
public static final int LOGIC_CONTINUOUS = 0x02; public static final int LOGIC_CONTINUOUS = 0x02;
public static final int LOGIC_IGNORE_EXT = 0x04; 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_signal_ = false;
private boolean block_power_updated_ = false; private boolean block_power_updated_ = false;
private int logic_ = LOGIC_IGNORE_EXT | LOGIC_CONTINUOUS; private int logic_ = LOGIC_IGNORE_EXT | LOGIC_CONTINUOUS;
private int current_slot_index_ = 0; private int current_slot_index_ = 0;
private int tick_timer_ = 0; protected final ContainerData fields = new ContainerData() {
private final boolean debug_ = false; // @todo debug stick in `self::use()` toggling. @Override
private final Inventories.StorageInventory inventory_ = new Inventories.StorageInventory(this, NUM_OF_SLOTS, 1); public int getCount() {
private final LazyOptional<IItemHandler> item_handler_; 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); super(ModContent.getBlockEntityTypeOfBlock(state.getBlock()), pos, state);
item_handler_ = Inventories.MappedItemHandler.createGenericHandler(inventory_, item_handler_ = Inventories.MappedItemHandler.createGenericHandler(inventory_,
(stack, slot) -> true, (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(); CompoundTag nbt = new CompoundTag();
writenbt(nbt, false); writenbt(nbt, false);
inventory_.clearContent(); inventory_.clearContent();
@ -213,30 +244,28 @@ public class EdPlacer
return nbt; return nbt;
} }
public void reset_rtstate() public void reset_rtstate() {
{
block_power_signal_ = false; block_power_signal_ = false;
block_power_updated_ = false; block_power_updated_ = false;
} }
public void readnbt(CompoundTag nbt, boolean update_packet) public void readnbt(CompoundTag nbt, boolean update_packet) {
{
inventory_.load(nbt); inventory_.load(nbt);
block_power_signal_ = nbt.getBoolean("powered"); block_power_signal_ = nbt.getBoolean("powered");
current_slot_index_ = nbt.getInt("act_slot_index"); current_slot_index_ = nbt.getInt("act_slot_index");
logic_ = nbt.getInt("logic"); logic_ = nbt.getInt("logic");
} }
protected void writenbt(CompoundTag nbt, boolean update_packet) // BlockEntity ------------------------------------------------------------------------------
{
protected void writenbt(CompoundTag nbt, boolean update_packet) {
inventory_.save(nbt); inventory_.save(nbt);
nbt.putBoolean("powered", block_power_signal_); nbt.putBoolean("powered", block_power_signal_);
nbt.putInt("act_slot_index", current_slot_index_); nbt.putInt("act_slot_index", current_slot_index_);
nbt.putInt("logic", logic_); nbt.putInt("logic", logic_);
} }
public void block_updated() public void block_updated() {
{
boolean powered = level.hasNeighborSignal(worldPosition); boolean powered = level.hasNeighborSignal(worldPosition);
if (block_power_signal_ != powered) block_power_updated_ = true; if (block_power_signal_ != powered) block_power_updated_ = true;
block_power_signal_ = powered; block_power_signal_ = powered;
@ -247,95 +276,70 @@ public class EdPlacer
} }
} }
// BlockEntity ------------------------------------------------------------------------------
@Override @Override
public void load(CompoundTag nbt) public void load(CompoundTag nbt) {
{ super.load(nbt); readnbt(nbt, false); } 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 ----------------------------------------------------------------------------------------------- // Namable -----------------------------------------------------------------------------------------------
@Override @Override
public Component getName() protected void saveAdditional(CompoundTag nbt) {
{ return Auxiliaries.localizable(getBlockState().getBlock().getDescriptionId()); } super.saveAdditional(nbt);
writenbt(nbt, false);
}
@Override @Override
public boolean hasCustomName() public void setRemoved() {
{ return false; } super.setRemoved();
item_handler_.invalidate();
}
@Override @Override
public Component getCustomName() public Component getName() {
{ return getName(); } return Auxiliaries.localizable(getBlockState().getBlock().getDescriptionId());
}
// INamedContainerProvider ------------------------------------------------------------------------------ // INamedContainerProvider ------------------------------------------------------------------------------
@Override @Override
public Component getDisplayName() public boolean hasCustomName() {
{ return Nameable.super.getDisplayName(); } return false;
}
@Override @Override
public AbstractContainerMenu createMenu(int id, Inventory inventory, Player player ) public Component getCustomName() {
{ return new PlacerContainer(id, inventory, inventory_, ContainerLevelAccess.create(level, worldPosition), fields); } return getName();
}
// Fields ----------------------------------------------------------------------------------------------- // Fields -----------------------------------------------------------------------------------------------
protected final ContainerData fields = new ContainerData()
{
@Override @Override
public int getCount() public Component getDisplayName() {
{ return PlacerTileEntity.NUM_OF_FIELDS; } return Nameable.super.getDisplayName();
@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);
}
}
};
// Capability export ------------------------------------------------------------------------------------ // Capability export ------------------------------------------------------------------------------------
@Override @Override
public <T> LazyOptional<T> getCapability(net.minecraftforge.common.capabilities.Capability<T> capability, @Nullable Direction facing) public AbstractContainerMenu createMenu(int id, Inventory inventory, Player player) {
{ return new PlacerContainer(id, inventory, inventory_, ContainerLevelAccess.create(level, worldPosition), fields);
if(capability == ForgeCapabilities.ITEM_HANDLER) return item_handler_.cast();
return super.getCapability(capability, facing);
} }
// ITickable and aux methods ---------------------------------------------------------------------------- // ITickable and aux methods ----------------------------------------------------------------------------
private static int next_slot(int i) @Override
{ return (i<NUM_OF_SLOTS-1) ? (i+1) : 0; } 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) private boolean spit_out(Direction facing) {
{ return spit_out(facing, false); } 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 stack = inventory_.getItem(current_slot_index_);
ItemStack drop = stack.copy(); ItemStack drop = stack.copy();
if (!all) { if (!all) {
@ -355,8 +359,7 @@ public class EdPlacer
return true; return true;
} }
private boolean try_place(Direction facing, boolean triggered) private boolean try_place(Direction facing, boolean triggered) {
{
if (level.isClientSide()) return false; if (level.isClientSide()) return false;
BlockPos placement_pos = worldPosition.relative(facing); BlockPos placement_pos = worldPosition.relative(facing);
if (level.getBlockEntity(placement_pos) != null) return false; if (level.getBlockEntity(placement_pos) != null) return false;
@ -367,13 +370,17 @@ public class EdPlacer
if (!current_stack.isEmpty()) break; if (!current_stack.isEmpty()) break;
current_slot_index_ = next_slot(current_slot_index_); 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; boolean no_space = false;
final Item item = current_stack.getItem(); final Item item = current_stack.getItem();
Block block = Block.byItem(item); Block block = Block.byItem(item);
if (block == Blocks.AIR) { if (block == Blocks.AIR) {
if (item != null) { 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 return spit_out(facing); // Item not accepted
} }
} else if (block instanceof IPlantable) { } else if (block instanceof IPlantable) {
@ -404,19 +411,20 @@ public class EdPlacer
} }
} else { } else {
final BlockState current_placement_pos_state = level.getBlockState(placement_pos); final BlockState current_placement_pos_state = level.getBlockState(placement_pos);
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation") final boolean replacable = (current_placement_pos_state.getBlock().canBeReplaced(current_placement_pos_state, Fluids.EMPTY)) && (
final boolean replacable = (current_placement_pos_state.getBlock().canBeReplaced(current_placement_pos_state, Fluids.EMPTY)) && (
level.isEmptyBlock(placement_pos) || level.isEmptyBlock(placement_pos) ||
(current_placement_pos_state.getBlock() instanceof IFluidBlock) || (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) || ( if ((!replacable) || (
(!level.getEntitiesOfClass(Entity.class, new AABB(placement_pos), (Entity e) -> { (!level.getEntitiesOfClass(Entity.class, new AABB(placement_pos), (Entity e) -> {
if (e.isPickable()) return true; if (e.isPickable()) return true;
if (triggered) return false; if (triggered) return false;
if ((e instanceof ItemEntity)) { if ((e instanceof ItemEntity)) {
if((e.getDeltaMovement().y() > 0) || (e.getDeltaMovement().y() < -0.5)) return true; // not falling or falling by if ((e.getDeltaMovement().y() > 0) || (e.getDeltaMovement().y() < -0.5))
if(Math.abs(e.getDeltaMovement().x())+Math.abs(e.getDeltaMovement().z()) > 0) return true; // not straight 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; return false;
}).isEmpty()) }).isEmpty())
@ -449,22 +457,26 @@ public class EdPlacer
} }
BlockState placement_state = (use_context == null) ? (block.defaultBlockState()) : (block.getStateForPlacement(use_context)); BlockState placement_state = (use_context == null) ? (block.defaultBlockState()) : (block.getStateForPlacement(use_context));
if (placement_state == null) { 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); return spit_out(facing);
} else if ((use_context != null) && (item instanceof BlockItem)) { } else if ((use_context != null) && (item instanceof BlockItem)) {
if (((BlockItem) item).place(use_context) != InteractionResult.FAIL) { if (((BlockItem) item).place(use_context) != InteractionResult.FAIL) {
SoundType stype = block.getSoundType(placement_state, level, worldPosition, null); 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 { } else {
if (level.setBlock(placement_pos, placement_state, 1 | 2 | 8)) { if (level.setBlock(placement_pos, placement_state, 1 | 2 | 8)) {
SoundType stype = block.getSoundType(placement_state, level, worldPosition, null); 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 { } else {
if (level.setBlock(placement_pos, placement_state, 1 | 2 | 8)) { if (level.setBlock(placement_pos, placement_state, 1 | 2 | 8)) {
SoundType stype = block.getSoundType(placement_state, level, worldPosition, null); 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); current_stack.shrink(1);
@ -494,15 +506,17 @@ public class EdPlacer
} }
@Override @Override
public void tick() public void tick() {
{
// Tick cycle pre-conditions // Tick cycle pre-conditions
if (level.isClientSide) return; if (level.isClientSide) return;
if (--tick_timer_ > 0) return; if (--tick_timer_ > 0) return;
tick_timer_ = TICK_INTERVAL; tick_timer_ = TICK_INTERVAL;
// Cycle init // Cycle init
final BlockState state = level.getBlockState(worldPosition); 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 updated = block_power_updated_;
final boolean rssignal = ((logic_ & LOGIC_IGNORE_EXT) != 0) || ((logic_ & LOGIC_INVERTED) != 0) == (!block_power_signal_); 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))); final boolean trigger = ((logic_ & LOGIC_IGNORE_EXT) != 0) || (rssignal && ((updated) || ((logic_ & LOGIC_CONTINUOUS) != 0)));
@ -526,8 +540,7 @@ public class EdPlacer
// Container // 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"; protected static final String QUICK_MOVE_ALL = "quick-move-all";
private static final int PLAYER_INV_START_SLOTNO = PlacerTileEntity.NUM_OF_SLOTS; private static final int PLAYER_INV_START_SLOTNO = PlacerTileEntity.NUM_OF_SLOTS;
private final Player player_; private final Player player_;
@ -537,13 +550,11 @@ public class EdPlacer
private final Inventories.InventoryRange player_inventory_range_; private final Inventories.InventoryRange player_inventory_range_;
private final Inventories.InventoryRange block_storage_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) private PlacerContainer(int cid, Inventory player_inventory, Container block_inventory, ContainerLevelAccess wpc, ContainerData fields) {
{ 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)
{
super(ModContent.getMenuType("factory_placer"), cid); // @todo: class mapping super(ModContent.getMenuType("factory_placer"), cid); // @todo: class mapping
fields_ = fields; fields_ = fields;
wpc_ = wpc; wpc_ = wpc;
@ -571,20 +582,25 @@ public class EdPlacer
this.addDataSlots(fields_); // === Add reference holders this.addDataSlots(fields_); // === Add reference holders
} }
@Override public final int field(int index) {
public boolean stillValid(Player player) return fields_.get(index);
{ return inventory_.stillValid(player); } }
@Override @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); Slot slot = getSlot(index);
if ((slot == null) || (!slot.hasItem())) return ItemStack.EMPTY; if ((slot == null) || (!slot.hasItem())) return ItemStack.EMPTY;
ItemStack slot_stack = slot.getItem(); ItemStack slot_stack = slot.getItem();
ItemStack transferred = slot_stack.copy(); ItemStack transferred = slot_stack.copy();
if ((index >= 0) && (index < PLAYER_INV_START_SLOTNO)) { if ((index >= 0) && (index < PLAYER_INV_START_SLOTNO)) {
// Device slots // 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)) { } else if ((index >= PLAYER_INV_START_SLOTNO) && (index <= PLAYER_INV_START_SLOTNO + 36)) {
// Player slot // Player slot
if (!moveItemStackTo(slot_stack, 0, PlacerTileEntity.NUM_OF_SLOTS, false)) return ItemStack.EMPTY; if (!moveItemStackTo(slot_stack, 0, PlacerTileEntity.NUM_OF_SLOTS, false)) return ItemStack.EMPTY;
@ -605,33 +621,32 @@ public class EdPlacer
// INetworkSynchronisableContainer --------------------------------------------------------- // INetworkSynchronisableContainer ---------------------------------------------------------
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public void onGuiAction(CompoundTag nbt) public void onGuiAction(CompoundTag nbt) {
{ Networking.PacketContainerSyncClientToServer.sendToServer(containerId, nbt); } Networking.PacketContainerSyncClientToServer.sendToServer(containerId, nbt);
}
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public void onGuiAction(String key, int value) public void onGuiAction(String key, int value) {
{
CompoundTag nbt = new CompoundTag(); CompoundTag nbt = new CompoundTag();
nbt.putInt(key, value); nbt.putInt(key, value);
Networking.PacketContainerSyncClientToServer.sendToServer(containerId, nbt); Networking.PacketContainerSyncClientToServer.sendToServer(containerId, nbt);
} }
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public void onGuiAction(String message, CompoundTag nbt) public void onGuiAction(String message, CompoundTag nbt) {
{
nbt.putString("action", message); nbt.putString("action", message);
Networking.PacketContainerSyncClientToServer.sendToServer(containerId, nbt); Networking.PacketContainerSyncClientToServer.sendToServer(containerId, nbt);
} }
@Override @Override
public void onServerPacketReceived(int windowId, CompoundTag nbt) public void onServerPacketReceived(int windowId, CompoundTag nbt) {
{} }
@Override @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 (!(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")) { if (nbt.contains("action")) {
final int slotId = nbt.contains("slot") ? nbt.getInt("slot") : -1; final int slotId = nbt.contains("slot") ? nbt.getInt("slot") : -1;
boolean changed = false; boolean changed = false;
@ -651,7 +666,11 @@ public class EdPlacer
} }
} else { } else {
if (nbt.contains("logic")) te.logic_ = nbt.getInt("logic"); 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(); te.setChanged();
} }
@ -663,14 +682,13 @@ public class EdPlacer
//-------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public static class PlacerGui extends Guis.ContainerGui<PlacerContainer> public static class PlacerGui extends Guis.ContainerGui<PlacerContainer> {
{ public PlacerGui(PlacerContainer container, Inventory player_inventory, Component title) {
public PlacerGui(PlacerContainer container, Inventory player_inventory, Component title) super(container, player_inventory, title, "textures/gui/factory_placer_gui.png");
{ super(container, player_inventory, title,"textures/gui/factory_placer_gui.png"); } }
@Override @Override
public void init() public void init() {
{
super.init(); super.init();
{ {
final Block block = ModContent.getBlock(Auxiliaries.getResourceLocation(getMenu().getType()).getPath().replaceAll("^ct_", "")); final Block block = ModContent.getBlock(Auxiliaries.getResourceLocation(getMenu().getType()).getPath().replaceAll("^ct_", ""));
@ -685,8 +703,7 @@ public class EdPlacer
} }
@Override @Override
public boolean mouseClicked(double mouseX, double mouseY, int mouseButton) public boolean mouseClicked(double mouseX, double mouseY, int mouseButton) {
{
tooltip_.resetTimer(); tooltip_.resetTimer();
PlacerContainer container = getMenu(); PlacerContainer container = getMenu();
int mx = (int) (mouseX - getGuiLeft() + .5), my = (int) (mouseY - getGuiTop() + .5); int mx = (int) (mouseX - getGuiLeft() + .5), my = (int) (mouseY - getGuiTop() + .5);
@ -710,8 +727,7 @@ public class EdPlacer
} }
@Override @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(); tooltip_.resetTimer();
if ((type == ClickType.QUICK_MOVE) && (slot != null) && slot.hasItem() && Auxiliaries.isShiftDown() && Auxiliaries.isCtrlDown()) { if ((type == ClickType.QUICK_MOVE) && (slot != null) && slot.hasItem() && Auxiliaries.isShiftDown() && Auxiliaries.isCtrlDown()) {
CompoundTag nbt = new CompoundTag(); CompoundTag nbt = new CompoundTag();
@ -723,8 +739,7 @@ public class EdPlacer
} }
@Override @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(); final int x0 = getGuiLeft(), y0 = getGuiTop(), w = getXSize(), h = getYSize();
PlacerContainer container = getMenu(); PlacerContainer container = getMenu();
// active slot // active slot
@ -733,21 +748,21 @@ public class EdPlacer
if ((slot_index < 0) || (slot_index >= PlacerTileEntity.NUM_OF_SLOTS)) slot_index = 0; if ((slot_index < 0) || (slot_index >= PlacerTileEntity.NUM_OF_SLOTS)) slot_index = 0;
int x = (x0 + 10 + ((slot_index % 6) * 18)); int x = (x0 + 10 + ((slot_index % 6) * 18));
int y = (y0 + 8 + ((slot_index / 6) * 17)); 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 // redstone input
{ {
if (container.field(1) != 0) { 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 // trigger logic
{ {
int inverter_offset_x = ((container.field(0) & PlacerTileEntity.LOGIC_INVERTED) != 0) ? 11 : 0; 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; 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; 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; 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.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.world.item.context.BlockPlaceContext; 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.minecraft.world.phys.shapes.VoxelShape;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; 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<StairsShape> SHAPE = BlockStateProperties.STAIRS_SHAPE;
public static final EnumProperty<Half> HALF = BlockStateProperties.HALF; public static final EnumProperty<Half> HALF = BlockStateProperties.HALF;
private final VoxelShape[][][] shape_cache_; private final VoxelShape[][][] shape_cache_;
public EdRoofBlock(long config, BlockBehaviour.Properties properties) public EdRoofBlock(long config, BlockBehaviour.Properties properties) {
{ this(config, properties.dynamicShape(), Shapes.empty(), Shapes.empty()); } 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)); super(config, properties, Auxiliaries.getPixeledAABB(0, 0, 0, 16, 8, 16));
registerDefaultState(super.defaultBlockState().setValue(HORIZONTAL_FACING, Direction.NORTH).setValue(SHAPE, StairsShape.STRAIGHT)); registerDefaultState(super.defaultBlockState().setValue(HORIZONTAL_FACING, Direction.NORTH).setValue(SHAPE, StairsShape.STRAIGHT));
shape_cache_ = makeShapes(add, cut); shape_cache_ = makeShapes(add, cut);
} }
@Override private static boolean isRoofBlock(BlockState state) {
@SuppressWarnings("deprecation") return (state.getBlock() instanceof EdRoofBlock);
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 private static boolean isOtherRoofState(BlockState state, BlockGetter world, BlockPos pos, Direction facing) {
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)
{
BlockState st = world.getBlockState(pos.relative(facing)); BlockState st = world.getBlockState(pos.relative(facing));
return (!isRoofBlock(st)) || (st.getValue(HORIZONTAL_FACING) != state.getValue(HORIZONTAL_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]; VoxelShape[][][] shapes = new VoxelShape[2][6][5];
for (int half_index = 0; half_index < Half.values().length; ++half_index) { for (int half_index = 0; half_index < Half.values().length; ++half_index) {
for (int direction_index = 0; direction_index < Direction.values().length; ++direction_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; 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[]{ AABB[] straight = new AABB[]{
Auxiliaries.getPixeledAABB(0, 0, 0, 16, 4, 16), Auxiliaries.getPixeledAABB(0, 0, 0, 16, 4, 16),
Auxiliaries.getPixeledAABB(4, 4, 0, 16, 8, 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); Direction direction = state.getValue(HORIZONTAL_FACING);
{ {
BlockState ns = world.getBlockState(pos.relative(direction)); BlockState ns = world.getBlockState(pos.relative(direction));
@ -227,4 +141,93 @@ public class EdRoofBlock extends StandardBlocks.HorizontalWaterLoggable
} }
return StairsShape.STRAIGHT; 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; 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.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
@ -16,8 +19,8 @@ import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult; import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelReader;
import net.minecraft.world.level.LightLayer; 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.Block;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockBehaviour; 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.capabilities.ForgeCapabilities;
import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.energy.IEnergyStorage; 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 javax.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class EdSolarPanel public class EdSolarPanel {
{
public static final int DEFAULT_PEAK_POWER = 40; public static final int DEFAULT_PEAK_POWER = 40;
private static int peak_power_per_tick_ = DEFAULT_PEAK_POWER; private static int peak_power_per_tick_ = DEFAULT_PEAK_POWER;
private static int max_power_storage_ = 64000; 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 feeding_threshold = max_power_storage_ / 5;
private static int balancing_threshold = max_power_storage_ / 10; 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; final int t = SolarPanelTileEntity.TICK_INTERVAL;
peak_power_per_tick_ = Mth.clamp(peak_power_per_tick, 12, 8192); peak_power_per_tick_ = Mth.clamp(peak_power_per_tick, 12, 8192);
feeding_threshold = Math.max(max_power_storage_ / 5, 1000); feeding_threshold = Math.max(max_power_storage_ / 5, 1000);
@ -65,28 +59,28 @@ public class EdSolarPanel
// Block // 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 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); super(config, builder, unrotatedAABB);
registerDefaultState(super.defaultBlockState().setValue(EXPOSITION, 1)); registerDefaultState(super.defaultBlockState().setValue(EXPOSITION, 1));
} }
@Override @Override
public boolean isBlockEntityTicking(Level world, BlockState state) public boolean isBlockEntityTicking(Level world, BlockState state) {
{ return true; } return true;
}
@Override @Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
{ super.createBlockStateDefinition(builder); builder.add(EXPOSITION); } super.createBlockStateDefinition(builder);
builder.add(EXPOSITION);
}
@Override @Override
@SuppressWarnings("deprecation") @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; if (world.isClientSide()) return InteractionResult.SUCCESS;
BlockEntity te = world.getBlockEntity(pos); BlockEntity te = world.getBlockEntity(pos);
if (te instanceof SolarPanelTileEntity) ((SolarPanelTileEntity) te).state_message(player); if (te instanceof SolarPanelTileEntity) ((SolarPanelTileEntity) te).state_message(player);
@ -94,42 +88,42 @@ public class EdSolarPanel
} }
@Override @Override
public boolean shouldCheckWeakPower(BlockState state, LevelReader world, BlockPos pos, Direction side) public boolean shouldCheckWeakPower(BlockState state, SignalGetter level, BlockPos pos, Direction side) {
{ return false; } return false;
}
} }
//-------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------
// Tile entity // 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 TICK_INTERVAL = 4;
public static final int ACCUMULATION_INTERVAL = 8; public static final int ACCUMULATION_INTERVAL = 8;
private static final Direction[] transfer_directions_ = {Direction.DOWN, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.NORTH}; 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 tick_timer_ = 0;
private int recalc_timer_ = 0; private int recalc_timer_ = 0;
private int current_production_ = 0; private int current_production_ = 0;
private int current_feedin_ = 0; private int current_feedin_ = 0;
private boolean output_enabled_ = false; 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) public SolarPanelTileEntity(BlockPos pos, BlockState state) {
{ super(ModContent.getBlockEntityTypeOfBlock(state.getBlock()), pos, state); } super(ModContent.getBlockEntityTypeOfBlock(state.getBlock()), pos, state);
}
public void readnbt(CompoundTag nbt, boolean update_packet) public void readnbt(CompoundTag nbt, boolean update_packet) {
{ battery_.load(nbt); } battery_.load(nbt);
}
protected void writenbt(CompoundTag nbt, boolean update_packet) protected void writenbt(CompoundTag nbt, boolean update_packet) {
{ battery_.save(nbt); } 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)); 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_)); 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 --------------------------------------------------------------------- // ICapabilityProvider ---------------------------------------------------------------------
@Override @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(); if (capability == ForgeCapabilities.ENERGY) return energy_handler_.cast();
return super.getCapability(capability, facing); return super.getCapability(capability, facing);
} }
@ -146,23 +139,25 @@ public class EdSolarPanel
// BlockEntity ------------------------------------------------------------------------------ // BlockEntity ------------------------------------------------------------------------------
@Override @Override
public void load(CompoundTag nbt) public void load(CompoundTag nbt) {
{ super.load(nbt); readnbt(nbt, false); } super.load(nbt);
readnbt(nbt, false);
}
@Override @Override
protected void saveAdditional(CompoundTag nbt) protected void saveAdditional(CompoundTag nbt) {
{ super.saveAdditional(nbt); writenbt(nbt, false); } super.saveAdditional(nbt);
writenbt(nbt, false);
}
@Override @Override
public void setRemoved() public void setRemoved() {
{
super.setRemoved(); super.setRemoved();
energy_handler_.invalidate(); energy_handler_.invalidate();
} }
@Override @Override
public void tick() public void tick() {
{
if ((level.isClientSide) || (--tick_timer_ > 0)) return; if ((level.isClientSide) || (--tick_timer_ > 0)) return;
tick_timer_ = TICK_INTERVAL; tick_timer_ = TICK_INTERVAL;
BlockState state = level.getBlockState(worldPosition); BlockState state = level.getBlockState(worldPosition);
@ -190,7 +185,8 @@ public class EdSolarPanel
current_feedin_ /= TICK_INTERVAL; current_feedin_ /= TICK_INTERVAL;
if ((current_feedin_ <= 0) && ((battery_.getEnergyStored() >= balancing_threshold) || (current_production_ <= 0))) { if ((current_feedin_ <= 0) && ((battery_.getEnergyStored() >= balancing_threshold) || (current_production_ <= 0))) {
for (SolarPanelTileEntity panel : adjacent_panels) { 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); panel.battery_.setEnergyStored(panel.battery_.getEnergyStored() + balancing_threshold);
battery_.setEnergyStored(battery_.getEnergyStored() - balancing_threshold); battery_.setEnergyStored(battery_.getEnergyStored() - balancing_threshold);
if (battery_.getEnergyStored() < balancing_threshold) break; if (battery_.getEnergyStored() < balancing_threshold) break;
@ -200,7 +196,8 @@ public class EdSolarPanel
tick_timer_ = TICK_INTERVAL * 10; tick_timer_ = TICK_INTERVAL * 10;
current_production_ = 0; current_production_ = 0;
if ((!battery_.isEmpty())) output_enabled_ = true; 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; return;
} }
if (battery_.isEmpty()) output_enabled_ = false; if (battery_.isEmpty()) output_enabled_ = false;

View file

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

View file

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

View file

@ -8,7 +8,13 @@
*/ */
package dev.zontreck.engineerdecor.blocks; package dev.zontreck.engineerdecor.blocks;
import dev.zontreck.engineerdecor.ModConfig;
import dev.zontreck.engineerdecor.ModContent;
import dev.zontreck.engineerdecor.detail.TreeCutting; 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.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.core.particles.ParticleTypes; 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.entity.player.Player;
import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.item.context.BlockPlaceContext;
import net.minecraft.world.level.Level; 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.Block;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockBehaviour; 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.capabilities.ForgeCapabilities;
import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.energy.IEnergyStorage; 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 javax.annotation.Nullable;
import java.util.Random; import java.util.Random;
public class EdTreeCutter {
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 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 // 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 static final BooleanProperty ACTIVE = BooleanProperty.create("active");
public TreeCutterBlock(long config, BlockBehaviour.Properties builder, final AABB[] unrotatedAABB) public TreeCutterBlock(long config, BlockBehaviour.Properties builder, final AABB[] unrotatedAABB) {
{ super(config, builder, unrotatedAABB); } super(config, builder, unrotatedAABB);
}
@Override @Override
public boolean isBlockEntityTicking(Level world, BlockState state) public boolean isBlockEntityTicking(Level world, BlockState state) {
{ return true; } return true;
}
@Override @Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
{ super.createBlockStateDefinition(builder); builder.add(ACTIVE); } super.createBlockStateDefinition(builder);
builder.add(ACTIVE);
}
@Override @Override
@Nullable @Nullable
public BlockState getStateForPlacement(BlockPlaceContext context) public BlockState getStateForPlacement(BlockPlaceContext context) {
{ return super.getStateForPlacement(context).setValue(ACTIVE, false); } return super.getStateForPlacement(context).setValue(ACTIVE, false);
}
@OnlyIn(Dist.CLIENT) @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; if ((state.getBlock() != this) || (!state.getValue(ACTIVE))) return;
// Sound // 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); world.playLocalSound(pos.getX(), pos.getY(), pos.getZ(), SoundEvents.WOOD_HIT, SoundSource.BLOCKS, 0.1f, 1.0f, false);
} }
// Particles // Particles
@ -102,8 +105,7 @@ public class EdTreeCutter
@Override @Override
@SuppressWarnings("deprecation") @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; if (world.isClientSide()) return InteractionResult.SUCCESS;
BlockEntity te = world.getBlockEntity(pos); BlockEntity te = world.getBlockEntity(pos);
if (te instanceof TreeCutterTileEntity) ((TreeCutterTileEntity) te).state_message(player); if (te instanceof TreeCutterTileEntity) ((TreeCutterTileEntity) te).state_message(player);
@ -111,16 +113,16 @@ public class EdTreeCutter
} }
@Override @Override
public boolean shouldCheckWeakPower(BlockState state, LevelReader world, BlockPos pos, Direction side) public boolean shouldCheckWeakPower(BlockState state, SignalGetter level, BlockPos pos, Direction side) {
{ return false; } return false;
}
} }
//-------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------
// Tile entity // 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 IDLE_TICK_INTERVAL = 40;
public static final int TICK_INTERVAL = 5; public static final int TICK_INTERVAL = 5;
public static final int BOOST_FACTOR = 6; 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 energy_max = DEFAULT_BOOST_ENERGY * 20;
private static int cutting_time_needed = 20 * DEFAULT_CUTTING_TIME_NEEDED; private static int cutting_time_needed = 20 * DEFAULT_CUTTING_TIME_NEEDED;
private static boolean requires_power = false; private static boolean requires_power = false;
protected LazyOptional<IEnergyStorage> energy_handler_ = LazyOptional.of(() -> this);
private int tick_timer_; private int tick_timer_;
private int active_timer_; private int active_timer_;
private int proc_time_elapsed_; private int proc_time_elapsed_;
private int energy_; 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); boost_energy_consumption = TICK_INTERVAL * Mth.clamp(boost_energy_per_tick, 4, 4096);
energy_max = Math.max(boost_energy_consumption * 10, 10000); energy_max = Math.max(boost_energy_consumption * 10, 10000);
cutting_time_needed = 20 * Mth.clamp(cutting_time_seconds, 10, 240); 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."); 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) public void readnbt(CompoundTag nbt) {
{ super(ModContent.getBlockEntityTypeOfBlock(state.getBlock()), pos, state); } energy_ = nbt.getInt("energy");
}
public void readnbt(CompoundTag nbt) private void writenbt(CompoundTag nbt) {
{ energy_ = nbt.getInt("energy"); } nbt.putInt("energy", energy_);
}
private void writenbt(CompoundTag nbt) // BlockEntity ------------------------------------------------------------------------------
{ nbt.putInt("energy", energy_); }
public void state_message(Player player) public void state_message(Player player) {
{
String progress = "0"; String progress = "0";
if ((active_timer_ > 0) && (cutting_time_needed > 0) && (active_timer_ > 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)); 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))); 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 @Override
public void load(CompoundTag nbt) protected void saveAdditional(CompoundTag nbt) {
{ super.load(nbt); readnbt(nbt); } super.saveAdditional(nbt);
writenbt(nbt);
@Override
protected void saveAdditional(CompoundTag nbt)
{ super.saveAdditional(nbt); writenbt(nbt); }
@Override
public void setRemoved()
{
super.setRemoved();
energy_handler_.invalidate();
} }
// IEnergyStorage ---------------------------------------------------------------------------- // IEnergyStorage ----------------------------------------------------------------------------
protected LazyOptional<IEnergyStorage> energy_handler_ = LazyOptional.of(() -> this); @Override
public void setRemoved() {
super.setRemoved();
energy_handler_.invalidate();
}
@Override @Override
public boolean canExtract() public boolean canExtract() {
{ return false; } return false;
}
@Override @Override
public boolean canReceive() public boolean canReceive() {
{ return true; } return true;
}
@Override @Override
public int getMaxEnergyStored() public int getMaxEnergyStored() {
{ return boost_energy_consumption*2; } return boost_energy_consumption * 2;
}
@Override @Override
public int getEnergyStored() public int getEnergyStored() {
{ return energy_; } return energy_;
}
@Override @Override
public int extractEnergy(int maxExtract, boolean simulate) public int extractEnergy(int maxExtract, boolean simulate) {
{ return 0; } return 0;
}
@Override @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)); maxReceive = Mth.clamp(maxReceive, 0, Math.max((energy_max) - energy_, 0));
if (!simulate) energy_ += maxReceive; if (!simulate) energy_ += maxReceive;
return maxReceive; return maxReceive;
@ -216,8 +224,7 @@ public class EdTreeCutter
// Capability export ---------------------------------------------------------------------------- // Capability export ----------------------------------------------------------------------------
@Override @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(); if (capability == ForgeCapabilities.ENERGY) return energy_handler_.cast();
return super.getCapability(capability, facing); return super.getCapability(capability, facing);
} }
@ -225,8 +232,7 @@ public class EdTreeCutter
// ITickable ------------------------------------------------------------------------------------ // ITickable ------------------------------------------------------------------------------------
@Override @Override
public void tick() public void tick() {
{
if (--tick_timer_ > 0) return; if (--tick_timer_ > 0) return;
tick_timer_ = TICK_INTERVAL; tick_timer_ = TICK_INTERVAL;
final BlockState device_state = level.getBlockState(worldPosition); 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 BlockPos tree_pos = worldPosition.relative(device_state.getValue(TreeCutterBlock.HORIZONTAL_FACING));
final BlockState tree_state = level.getBlockState(tree_pos); final BlockState tree_state = level.getBlockState(tree_pos);
if (!TreeCutting.canChop(level, tree_state, tree_pos) || (level.hasNeighborSignal(worldPosition))) { 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; proc_time_elapsed_ = 0;
active_timer_ = 0; active_timer_ = 0;
tick_timer_ = IDLE_TICK_INTERVAL; tick_timer_ = IDLE_TICK_INTERVAL;

View file

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

View file

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

View file

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

View file

@ -8,6 +8,7 @@
*/ */
package dev.zontreck.engineerdecor.blocks; package dev.zontreck.engineerdecor.blocks;
import dev.zontreck.libzontreck.edlibmc.StandardBlocks;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.world.InteractionHand; 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.AABB;
import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import dev.zontreck.engineerdecor.libmc.StandardBlocks;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
@ -34,24 +34,25 @@ import java.util.Collections;
import java.util.List; import java.util.List;
public class EdgeAlignedRailingBlock extends StandardBlocks.HorizontalFourWayWaterLoggable public class EdgeAlignedRailingBlock extends StandardBlocks.HorizontalFourWayWaterLoggable {
{ public EdgeAlignedRailingBlock(long config, BlockBehaviour.Properties properties, final AABB base_aabb, final AABB railing_aabb) {
public EdgeAlignedRailingBlock(long config, BlockBehaviour.Properties properties, final AABB base_aabb, final AABB railing_aabb) super(config, properties, base_aabb, railing_aabb, 0);
{ super(config, properties, base_aabb, railing_aabb, 0); } }
@Override @Override
public boolean propagatesSkylightDown(BlockState state, BlockGetter reader, BlockPos pos) public boolean propagatesSkylightDown(BlockState state, BlockGetter reader, BlockPos pos) {
{ return true; } return true;
}
@Override @Override
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public boolean canBeReplaced(BlockState state, BlockPlaceContext useContext) public boolean canBeReplaced(BlockState state, BlockPlaceContext useContext) {
{ return (useContext.getItemInHand().getItem() == asItem()) || super.canBeReplaced(state, useContext); } return (useContext.getItemInHand().getItem() == asItem()) || super.canBeReplaced(state, useContext);
}
@Override @Override
@Nullable @Nullable
public BlockState getStateForPlacement(BlockPlaceContext context) public BlockState getStateForPlacement(BlockPlaceContext context) {
{
if (context.getClickedFace() != Direction.UP) return null; if (context.getClickedFace() != Direction.UP) return null;
BlockState state = context.getLevel().getBlockState(context.getClickedPos()); BlockState state = context.getLevel().getBlockState(context.getClickedPos());
if (state.getBlock() != this) state = super.getStateForPlacement(context); if (state.getBlock() != this) state = super.getStateForPlacement(context);
@ -62,13 +63,13 @@ public class EdgeAlignedRailingBlock extends StandardBlocks.HorizontalFourWayWat
@Override @Override
@SuppressWarnings("deprecation") @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; if (player.getItemInHand(hand).getItem() != asItem()) return InteractionResult.PASS;
Direction face = hit.getDirection(); Direction face = hit.getDirection();
if (!face.getAxis().isHorizontal()) return InteractionResult.sidedSuccess(world.isClientSide()); if (!face.getAxis().isHorizontal()) return InteractionResult.sidedSuccess(world.isClientSide());
final Vec3 rhv = hit.getLocation().subtract(Vec3.atCenterOf(hit.getBlockPos())); 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); BooleanProperty railing = getDirectionProperty(face);
boolean add = (!state.getValue(railing)); boolean add = (!state.getValue(railing));
state = state.setValue(railing, add); state = state.setValue(railing, add);
@ -84,12 +85,12 @@ public class EdgeAlignedRailingBlock extends StandardBlocks.HorizontalFourWayWat
// -- IDecorBlock // -- IDecorBlock
@Override @Override
public boolean hasDynamicDropList() public boolean hasDynamicDropList() {
{ return true; } return true;
}
@Override @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); if (world.isClientSide()) return Collections.singletonList(ItemStack.EMPTY);
List<ItemStack> drops = new ArrayList<>(); 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); 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; import net.minecraftforge.api.distmarker.OnlyIn;
public class ModRenderers public class ModRenderers {
{
//-------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------
// InvisibleEntityRenderer // InvisibleEntityRenderer
//-------------------------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------------------------
@OnlyIn(Dist.CLIENT) @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(); private final Minecraft mc = Minecraft.getInstance();
public InvisibleEntityRenderer(EntityRendererProvider.Context context) public InvisibleEntityRenderer(EntityRendererProvider.Context context) {
{ super(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) public Vec3 getRenderOffset(T entity, float partialTicks) {
{ return Vec3.ZERO; } return Vec3.ZERO;
}
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public ResourceLocation getTextureLocation(T entity) public ResourceLocation getTextureLocation(T entity) {
{ return TextureAtlas.LOCATION_BLOCKS; } return TextureAtlas.LOCATION_BLOCKS;
}
protected boolean shouldShowName(T entity) protected boolean shouldShowName(T entity) {
{ return false; } 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; package dev.zontreck.engineerdecor.detail;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import dev.zontreck.libzontreck.edlibmc.Auxiliaries;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Vec3i; import net.minecraft.core.Vec3i;
import net.minecraft.resources.ResourceLocation; 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.VineBlock;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.registries.ForgeRegistries;
import dev.zontreck.engineerdecor.libmc.Auxiliaries;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class TreeCutting public class TreeCutting {
{
private static final Set<Block> universal_logs_ = new HashSet<>(); 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(); universal_logs_.clear();
if (universal_logs.isEmpty()) return; if (universal_logs.isEmpty()) return;
try { 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( public static boolean canChop(Level world, BlockState state, BlockPos pos) {
new Vec3i( 1,0, 0), new Vec3i( 1,0, 1), new Vec3i( 0,0, 1), return isLog(state) || (universal_logs_.contains(state.getBlock()) && isLog(world.getBlockState(pos.above())));
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)
);
private static boolean isLog(BlockState state) private static boolean isLog(BlockState state) {
{ return (state.is(BlockTags.LOGS)); } 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 ba = a.getBlock();
final Block bb = b.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)); 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.getBlock() instanceof LeavesBlock) return true;
if (state.is(BlockTags.LEAVES)) return true; if (state.is(BlockTags.LEAVES)) return true;
return false; 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<>(); ArrayList<BlockPos> to_decay = new ArrayList<>();
for (int y = -1; y <= 1; ++y) { for (int y = -1; y <= 1; ++y) {
final BlockPos layer = centerPos.offset(0, y, 0); final BlockPos layer = centerPos.offset(0, y, 0);
@ -95,16 +91,15 @@ public class TreeCutting
return to_decay; 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); Block.dropResources(world.getBlockState(pos), world, pos);
world.setBlock(pos, world.getFluidState(pos).createLegacyBlock(), 1 | 2 | 8); 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 (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; if (!isLog(broken_state)) return 0;
final long ymin = startPos.getY(); final long ymin = startPos.getY();
final long max_leaf_distance = 8; final long max_leaf_distance = 8;
@ -158,7 +153,8 @@ public class TreeCutting
final BlockPos p = pos.offset(v); final BlockPos p = pos.offset(v);
if (checked.contains(p)) continue; if (checked.contains(p)) continue;
checked.add(p); 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 BlockState st = world.getBlockState(p);
final Block bl = st.getBlock(); final Block bl = st.getBlock();
if (isSameLog(st, broken_state)) { if (isSameLog(st, broken_state)) {

View file

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

View file

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