Skip to content

Commit

Permalink
Add dispensing minecarts with dispenser
Browse files Browse the repository at this point in the history
  • Loading branch information
P3pp3rF1y committed Dec 27, 2024
1 parent b7cc220 commit 9063b28
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import net.neoforged.bus.api.IEventBus;
import net.neoforged.fml.ModContainer;
import net.neoforged.fml.common.Mod;
import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent;
import net.p3pp3rf1y.sophisticatedstorageinmotion.client.ClientEventHandler;
import net.p3pp3rf1y.sophisticatedstorageinmotion.common.CommonEventHandler;
import net.p3pp3rf1y.sophisticatedstorageinmotion.data.DataGenerators;
Expand All @@ -29,6 +30,7 @@ public SophisticatedStorageInMotion(IEventBus modBus, Dist dist, ModContainer co
}
modBus.addListener(ModPayloads::registerPayloads);
modBus.addListener(DataGenerators::gatherData);
modBus.addListener(SophisticatedStorageInMotion::setup);
}

public static ResourceLocation getRL(String regName) {
Expand All @@ -38,4 +40,8 @@ public static ResourceLocation getRL(String regName) {
public static String getRegistryName(String regName) {
return MOD_ID + ":" + regName;
}

private static void setup(FMLCommonSetupEvent event) {
event.enqueueWork(ModItems::registerDispenseBehavior);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.RecipeSerializer;
import net.minecraft.world.item.crafting.SimpleCraftingRecipeSerializer;
import net.minecraft.world.level.block.DispenserBlock;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.neoforge.attachment.AttachmentType;
import net.neoforged.neoforge.registries.DeferredRegister;
Expand All @@ -33,7 +34,7 @@ private ModItems() {

private static final DeferredRegister<RecipeSerializer<?>> RECIPE_SERIALIZERS = DeferredRegister.create(BuiltInRegistries.RECIPE_SERIALIZER, SophisticatedStorageInMotion.MOD_ID);
public static final Supplier<RecipeSerializer<?>> MOVING_STORAGE_FROM_STORAGE_SERIALIZER = RECIPE_SERIALIZERS.register("moving_storage_from_storage", MovingStorageFromStorageRecipe.Serializer::new);
public static final Supplier<RecipeSerializer<?>> UNCRAFT_MOVING_STORAGE_SERIALIZER = RECIPE_SERIALIZERS.register("uncraft_moving_storage",() -> new SimpleCraftingRecipeSerializer<>(UncraftMovingStorageRecipe::new));
public static final Supplier<RecipeSerializer<?>> UNCRAFT_MOVING_STORAGE_SERIALIZER = RECIPE_SERIALIZERS.register("uncraft_moving_storage", () -> new SimpleCraftingRecipeSerializer<>(UncraftMovingStorageRecipe::new));

public static Supplier<CreativeModeTab> CREATIVE_TAB = CREATIVE_MODE_TABS.register("main", () ->
CreativeModeTab.builder().icon(() -> new ItemStack(STORAGE_MINECART.get()))
Expand All @@ -49,4 +50,8 @@ public static void registerHandlers(IEventBus modBus) {
ATTACHMENT_TYPES.register(modBus);
RECIPE_SERIALIZERS.register(modBus);
}

public static void registerDispenseBehavior() {
DispenserBlock.registerBehavior(STORAGE_MINECART.get(), StorageMinecartItem.DISPENSE_ITEM_BEHAVIOR);
}
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,68 @@
package net.p3pp3rf1y.sophisticatedstorageinmotion.item;

import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.dispenser.BlockSource;
import net.minecraft.core.dispenser.DefaultDispenseItemBehavior;
import net.minecraft.core.dispenser.DispenseItemBehavior;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.tags.BlockTags;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.BaseRailBlock;
import net.minecraft.world.level.block.DispenserBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.RailShape;
import net.minecraft.world.level.gameevent.GameEvent;
import net.p3pp3rf1y.sophisticatedstorageinmotion.entity.StorageMinecart;
import org.jetbrains.annotations.Nullable;

public class StorageMinecartItem extends MovingStorageItem {
public static final DispenseItemBehavior DISPENSE_ITEM_BEHAVIOR = new DefaultDispenseItemBehavior() {
private final DefaultDispenseItemBehavior defaultDispenseItemBehavior = new DefaultDispenseItemBehavior();

public ItemStack execute(BlockSource blockSource, ItemStack stack) {
Direction direction = blockSource.state().getValue(DispenserBlock.FACING);
ServerLevel serverlevel = blockSource.level();
BlockPos blockpos = blockSource.pos().relative(direction);
BlockState blockstate = serverlevel.getBlockState(blockpos);
RailShape railshape = blockstate.getBlock() instanceof BaseRailBlock baseRailBlock ? baseRailBlock.getRailDirection(blockstate, serverlevel, blockpos, null) : RailShape.NORTH_SOUTH;
double slopeOffset;
if (blockstate.is(BlockTags.RAILS)) {
if (railshape.isAscending()) {
slopeOffset = 0.6;
} else {
slopeOffset = 0.1;
}
} else {
if (!blockstate.isAir() || !serverlevel.getBlockState(blockpos.below()).is(BlockTags.RAILS)) {
return this.defaultDispenseItemBehavior.dispense(blockSource, stack);
}

BlockState stateBelow = serverlevel.getBlockState(blockpos.below());
RailShape railShapeBelow = stateBelow.getBlock() instanceof BaseRailBlock baseRailBlock ? baseRailBlock.getRailDirection(stateBelow, serverlevel, blockpos.below(), null) : RailShape.NORTH_SOUTH;
if (direction != Direction.DOWN && railShapeBelow.isAscending()) {
slopeOffset = -0.4;
} else {
slopeOffset = -0.9;
}
}

serverlevel.addFreshEntity(createMinecart(serverlevel, blockpos, slopeOffset, stack, null));
stack.shrink(1);
return stack;
}

protected void playSound(BlockSource blockSource) {
blockSource.level().levelEvent(1000, blockSource.pos(), 0);
}
};

public StorageMinecartItem() {
super(new Properties().stacksTo(1));
}
Expand All @@ -36,19 +83,24 @@ public InteractionResult useOn(UseOnContext context) {
ascendingOffset = 0.5;
}

StorageMinecart minecart = new StorageMinecart(level, blockpos.getX() + 0.5, blockpos.getY() + 0.0625 + ascendingOffset, blockpos.getZ() + 0.5);
minecart.getStorageHolder().setStorageItemFrom(stack);
EntityType.createDefaultStackConfig(serverlevel, stack, context.getPlayer()).accept(minecart);
Player player = context.getPlayer();

serverlevel.addFreshEntity(minecart);
serverlevel.gameEvent(GameEvent.ENTITY_PLACE, blockpos, GameEvent.Context.of(context.getPlayer(), serverlevel.getBlockState(blockpos.below())));
serverlevel.addFreshEntity(createMinecart(serverlevel, blockpos, ascendingOffset, stack, player));
serverlevel.gameEvent(GameEvent.ENTITY_PLACE, blockpos, GameEvent.Context.of(player, serverlevel.getBlockState(blockpos.below())));
}

stack.shrink(1);
return InteractionResult.sidedSuccess(level.isClientSide);
}
}

private static StorageMinecart createMinecart(ServerLevel serverlevel, BlockPos blockpos, double ascendingOffset, ItemStack stack, @Nullable Player player) {
StorageMinecart minecart = new StorageMinecart(serverlevel, blockpos.getX() + 0.5, blockpos.getY() + 0.0625 + ascendingOffset, blockpos.getZ() + 0.5);
minecart.getStorageHolder().setStorageItemFrom(stack);
EntityType.createDefaultStackConfig(serverlevel, stack, player).accept(minecart);
return minecart;
}

@Override
public ItemStack getUncraftRemainingItem() {
return new ItemStack(Items.MINECART);
Expand Down

0 comments on commit 9063b28

Please sign in to comment.