Skip to content

Commit

Permalink
Add MEGA crafting storage (#1)
Browse files Browse the repository at this point in the history
* Initial crafting storage attempt
see AppliedEnergistics/Applied-Energistics-2#6277

* Remove custom BE classes in favour of instantiating AE2's own

* Remove redundant custom block classes

* ditto

* Optimise textures

* Use switch statement to retrieve item for block entity
Fixes constantly returning null due to init order

* Try to fix model rendering?

* Add block drops and crafting recipes

* Move material definitions to provider class

* Add 4 co-processing threads to MEGA accelerator

* Terminology change

* Too many subpackages

* Fix incorrect monitor blockmodel

* Add missing client init, finally render CPUs properly as cutout

* Change formed colour scheme to full-black
they looked more like massive footballs prior to this

* Final(?) tweaks for PR

* Update mods.toml

* Update dependencies
  • Loading branch information
62832 authored Jun 4, 2022
1 parent 72e425a commit d8250c8
Show file tree
Hide file tree
Showing 62 changed files with 1,123 additions and 33 deletions.
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ apply(plugin: "net.minecraftforge.gradle")
apply plugin: 'org.spongepowered.mixin'

group = "ninety"
version = "1.1.1"
version = "1.2.0"

repositories {
maven {
Expand Down
10 changes: 5 additions & 5 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
minecraft_version=1.18.2
forge_version=40.0.44
ae2_version=11.0.0
jei_version=9.7.0.180
mekanism_version=10.2.0.459
appmek_fileid=3793491
forge_version=40.1.31
ae2_version=11.1.0
jei_version=9.7.0.195
mekanism_version=10.2.2.462
appmek_fileid=3807443

# Temp fix for Spotless / Remove Unused Imports:
# https://github.com/diffplug/spotless/issues/834
Expand Down
16 changes: 11 additions & 5 deletions src/main/java/ninety/megacells/MEGACells.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.DistExecutor;
Expand All @@ -10,10 +12,8 @@
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;

import ninety.megacells.datagen.MEGADataGenerators;
import ninety.megacells.init.InitCellModels;
import ninety.megacells.init.InitItems;
import ninety.megacells.init.InitUpgrades;
import ninety.megacells.init.client.InitItemColors;
import ninety.megacells.init.*;
import ninety.megacells.init.client.*;

@Mod(MEGACells.MODID)
public class MEGACells {
Expand All @@ -28,13 +28,19 @@ public MEGACells() {
IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus();

bus.addGenericListener(Item.class, InitItems::register);
bus.addGenericListener(Block.class, InitBlocks::register);
bus.addGenericListener(BlockEntityType.class, InitBlockEntities::register);

bus.addListener(MEGADataGenerators::onGatherData);
bus.addListener((FMLCommonSetupEvent event) -> {
event.enqueueWork(InitCellModels::init);
event.enqueueWork(InitUpgrades::init);
});

DistExecutor.safeRunWhenOn(Dist.CLIENT, () -> InitItemColors::initialize);
DistExecutor.safeRunWhenOn(Dist.CLIENT, () -> InitAutoRotatingModel::init);
DistExecutor.safeRunWhenOn(Dist.CLIENT, () -> InitBlockEntityRenderers::init);
DistExecutor.safeRunWhenOn(Dist.CLIENT, () -> InitBuiltInModels::init);
DistExecutor.safeRunWhenOn(Dist.CLIENT, () -> InitItemColors::init);
DistExecutor.safeRunWhenOn(Dist.CLIENT, () -> InitRenderTypes::init);
}
}
110 changes: 110 additions & 0 deletions src/main/java/ninety/megacells/block/MEGABlocks.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package ninety.megacells.block;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.function.BiFunction;
import java.util.function.Supplier;

import javax.annotation.Nullable;

import com.google.common.base.Preconditions;

import org.jetbrains.annotations.NotNull;

import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.SoundType;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.material.Material;

import appeng.block.crafting.CraftingMonitorBlock;
import appeng.block.crafting.CraftingUnitBlock;
import appeng.core.definitions.AEItems;
import appeng.core.definitions.AEParts;

import ninety.megacells.MEGACells;
import ninety.megacells.item.MEGAItems;

public class MEGABlocks {

private static final List<BlockDefinition<?>> BLOCKS = new ArrayList<>();

public static List<BlockDefinition<?>> getBlocks() {
return Collections.unmodifiableList(BLOCKS);
}

private static BlockBehaviour.Properties props = BlockBehaviour.Properties.of(Material.METAL)
.strength(2.2f, 11.0f)
.sound(SoundType.METAL);

// spotless:off
public static final BlockDefinition<CraftingUnitBlock> MEGA_CRAFTING_UNIT = block("mega_crafting_unit", () -> new CraftingUnitBlock(props, MEGACraftingUnitType.UNIT));
public static final BlockDefinition<CraftingUnitBlock> CRAFTING_ACCELERATOR = craftingBlock("mega_crafting_accelerator", () -> new CraftingUnitBlock(props, MEGACraftingUnitType.ACCELERATOR), () -> AEItems.ENGINEERING_PROCESSOR);
public static final BlockDefinition<CraftingUnitBlock> CRAFTING_STORAGE_1M = craftingBlock("1m_crafting_storage", () -> new CraftingUnitBlock(props, MEGACraftingUnitType.STORAGE_1M), () -> MEGAItems.CELL_COMPONENT_1M);
public static final BlockDefinition<CraftingUnitBlock> CRAFTING_STORAGE_4M = craftingBlock("4m_crafting_storage", () -> new CraftingUnitBlock(props, MEGACraftingUnitType.STORAGE_4M), () -> MEGAItems.CELL_COMPONENT_4M);
public static final BlockDefinition<CraftingUnitBlock> CRAFTING_STORAGE_16M = craftingBlock("16m_crafting_storage", () -> new CraftingUnitBlock(props, MEGACraftingUnitType.STORAGE_16M), () -> MEGAItems.CELL_COMPONENT_16M);
public static final BlockDefinition<CraftingUnitBlock> CRAFTING_STORAGE_64M = craftingBlock("64m_crafting_storage", () -> new CraftingUnitBlock(props, MEGACraftingUnitType.STORAGE_64M), () -> MEGAItems.CELL_COMPONENT_64M);
public static final BlockDefinition<CraftingUnitBlock> CRAFTING_STORAGE_256M = craftingBlock("256m_crafting_storage", () -> new CraftingUnitBlock(props, MEGACraftingUnitType.STORAGE_256M), () -> MEGAItems.CELL_COMPONENT_256M);
public static final BlockDefinition<CraftingMonitorBlock> CRAFTING_MONITOR = craftingBlock("mega_crafting_monitor", () -> new CraftingMonitorBlock(props, MEGACraftingUnitType.MONITOR), () -> AEParts.STORAGE_MONITOR);
// spotless:on

private static <T extends Block> BlockDefinition<T> craftingBlock(String id, Supplier<T> blockSupplier,
Supplier<ItemLike> disassemblyExtra) {
return block(id, blockSupplier, (block, props) -> new MEGACraftingBlockItem(block, props, disassemblyExtra));
}

private static <T extends Block> BlockDefinition<T> block(String id, Supplier<T> blockSupplier) {
return block(id, blockSupplier, null);
}

private static <T extends Block> BlockDefinition<T> block(
String id,
Supplier<T> blockSupplier,
@Nullable BiFunction<Block, Item.Properties, BlockItem> itemFactory) {

// Create block and matching item
T block = blockSupplier.get();

Item.Properties itemProperties = new Item.Properties().tab(MEGAItems.CREATIVE_TAB);

BlockItem item;
if (itemFactory != null) {
item = itemFactory.apply(block, itemProperties);
if (item == null) {
throw new IllegalArgumentException("BlockItem factory for " + id + " returned null");
}
} else {
item = new BlockItem(block, itemProperties);
}

BlockDefinition<T> definition = new BlockDefinition<>(MEGACells.makeId(id), block, item);

BLOCKS.add(definition);
return definition;
}

public static class BlockDefinition<T extends Block> extends MEGAItems.ItemDefinition<BlockItem> {

private final T block;

public BlockDefinition(ResourceLocation id, T block, BlockItem item) {
super(id, item);
this.block = Objects.requireNonNull(block, "block");
}

public final @NotNull T asBlock() {
return this.block;
}

public final ItemStack stack(int stackSize) {
Preconditions.checkArgument(stackSize > 0);
return new ItemStack(block, stackSize);
}
}
}
35 changes: 35 additions & 0 deletions src/main/java/ninety/megacells/block/MEGACraftingBlockItem.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package ninety.megacells.block;

import java.util.function.Supplier;

import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResultHolder;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;

import appeng.block.crafting.CraftingBlockItem;
import appeng.core.AEConfig;
import appeng.util.InteractionUtil;

public class MEGACraftingBlockItem extends CraftingBlockItem {
public MEGACraftingBlockItem(Block id, Properties props, Supplier<ItemLike> disassemblyExtra) {
super(id, props, disassemblyExtra);
}

@Override
public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand hand) {
if (AEConfig.instance().isDisassemblyCraftingEnabled() && InteractionUtil.isInAlternateUseMode(player)) {
int itemCount = player.getItemInHand(hand).getCount();
player.setItemInHand(hand, ItemStack.EMPTY);

player.getInventory().placeItemBackInInventory(MEGABlocks.MEGA_CRAFTING_UNIT.stack(itemCount));
player.getInventory().placeItemBackInInventory(new ItemStack(disassemblyExtra.get(), itemCount));

return InteractionResultHolder.sidedSuccess(player.getItemInHand(hand), level.isClientSide());
}
return super.use(level, player, hand);
}
}
53 changes: 53 additions & 0 deletions src/main/java/ninety/megacells/block/MEGACraftingUnitType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package ninety.megacells.block;

import net.minecraft.world.item.Item;

import appeng.block.crafting.ICraftingUnitType;

public enum MEGACraftingUnitType implements ICraftingUnitType {
UNIT(0, "unit"),
ACCELERATOR(0, "accelerator"),
STORAGE_1M(1, "1m_storage"),
STORAGE_4M(4, "4m_storage"),
STORAGE_16M(16, "16m_storage"),
STORAGE_64M(64, "64m_storage"),
STORAGE_256M(256, "256m_storage"),
MONITOR(0, "monitor");

private final int storageMb;
private final String affix;

MEGACraftingUnitType(int storageMb, String affix) {
this.storageMb = storageMb;
this.affix = affix;
}

@Override
public int getStorageBytes() {
return 1024 * 1024 * storageMb;
}

@Override
public int getAcceleratorThreads() {
return this == ACCELERATOR ? 4 : 0;
}

public String getAffix() {
return this.affix;
}

@Override
public Item getItemFromType() {
var definition = switch (this) {
case UNIT -> MEGABlocks.MEGA_CRAFTING_UNIT;
case ACCELERATOR -> MEGABlocks.CRAFTING_ACCELERATOR;
case STORAGE_1M -> MEGABlocks.CRAFTING_STORAGE_1M;
case STORAGE_4M -> MEGABlocks.CRAFTING_STORAGE_4M;
case STORAGE_16M -> MEGABlocks.CRAFTING_STORAGE_16M;
case STORAGE_64M -> MEGABlocks.CRAFTING_STORAGE_64M;
case STORAGE_256M -> MEGABlocks.CRAFTING_STORAGE_256M;
case MONITOR -> MEGABlocks.CRAFTING_MONITOR;
};
return definition.asItem();
}
}
86 changes: 86 additions & 0 deletions src/main/java/ninety/megacells/block/entity/MEGABlockEntities.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package ninety.megacells.block.entity;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;

import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.block.entity.BlockEntityTicker;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;

import appeng.block.AEBaseEntityBlock;
import appeng.blockentity.AEBaseBlockEntity;
import appeng.blockentity.ClientTickingBlockEntity;
import appeng.blockentity.ServerTickingBlockEntity;
import appeng.blockentity.crafting.CraftingBlockEntity;
import appeng.blockentity.crafting.CraftingMonitorBlockEntity;

import ninety.megacells.MEGACells;
import ninety.megacells.block.MEGABlocks;

@SuppressWarnings("unused")
public class MEGABlockEntities {

private static final Map<ResourceLocation, BlockEntityType<?>> BLOCK_ENTITY_TYPES = new HashMap<>();

public static Map<ResourceLocation, BlockEntityType<?>> getBlockEntityTypes() {
return ImmutableMap.copyOf(BLOCK_ENTITY_TYPES);
}

// spotless:off
public static final BlockEntityType<CraftingBlockEntity> MEGA_CRAFTING_UNIT = create("mega_crafting_unit", CraftingBlockEntity.class, CraftingBlockEntity::new, MEGABlocks.MEGA_CRAFTING_UNIT, MEGABlocks.CRAFTING_ACCELERATOR);
public static final BlockEntityType<CraftingBlockEntity> MEGA_CRAFTING_STORAGE = create("mega_crafting_storage", CraftingBlockEntity.class, CraftingBlockEntity::new, MEGABlocks.CRAFTING_STORAGE_1M, MEGABlocks.CRAFTING_STORAGE_4M, MEGABlocks.CRAFTING_STORAGE_16M, MEGABlocks.CRAFTING_STORAGE_64M, MEGABlocks.CRAFTING_STORAGE_256M);
public static final BlockEntityType<CraftingMonitorBlockEntity> MEGA_CRAFTING_MONITOR = create("mega_crafting_monitor", CraftingMonitorBlockEntity.class, CraftingMonitorBlockEntity::new, MEGABlocks.CRAFTING_MONITOR);
// spotless:on

@SafeVarargs
private static <T extends AEBaseBlockEntity> BlockEntityType<T> create(String id, Class<T> entityClass,
BlockEntityFactory<T> factory,
MEGABlocks.BlockDefinition<? extends AEBaseEntityBlock<?>>... blockDefinitions) {
Preconditions.checkArgument(blockDefinitions.length > 0);

var blocks = Arrays.stream(blockDefinitions)
.map(MEGABlocks.BlockDefinition::asBlock)
.toArray(AEBaseEntityBlock[]::new);

AtomicReference<BlockEntityType<T>> typeHolder = new AtomicReference<>();
BlockEntityType.BlockEntitySupplier<T> supplier = (blockPos, blockState) -> factory.create(typeHolder.get(),
blockPos, blockState);
var type = BlockEntityType.Builder.of(supplier, blocks).build(null);
type.setRegistryName(MEGACells.makeId(id));
typeHolder.set(type); // Makes it available to the supplier used above
BLOCK_ENTITY_TYPES.put(type.getRegistryName(), type);

AEBaseBlockEntity.registerBlockEntityItem(type, blockDefinitions[0].asItem());

// If the block entity classes implement specific interfaces, automatically register them
// as tickers with the blocks that create that entity.
BlockEntityTicker<T> serverTicker = null;
if (ServerTickingBlockEntity.class.isAssignableFrom(entityClass)) {
serverTicker = (level, pos, state, entity) -> ((ServerTickingBlockEntity) entity).serverTick();
}
BlockEntityTicker<T> clientTicker = null;
if (ClientTickingBlockEntity.class.isAssignableFrom(entityClass)) {
clientTicker = (level, pos, state, entity) -> ((ClientTickingBlockEntity) entity).clientTick();
}

for (var block : blocks) {
AEBaseEntityBlock<T> baseBlock = (AEBaseEntityBlock<T>) block;
baseBlock.setBlockEntity(entityClass, type, clientTicker, serverTicker);
}

return type;
}

@FunctionalInterface
interface BlockEntityFactory<T extends AEBaseBlockEntity> {
T create(BlockEntityType<T> type, BlockPos pos, BlockState state);
}

}
Loading

0 comments on commit d8250c8

Please sign in to comment.