Compare commits
40 Commits
plants-dev
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
489af3ef92 | ||
|
|
595901802c | ||
|
|
ef0a496cc7 | ||
|
|
0b9db5fd0e | ||
|
|
ec309be497 | ||
|
|
0809dca67f | ||
|
|
767a649ed6 | ||
|
|
312c7370cf | ||
|
|
1b7336e866 | ||
|
|
bccb0ef8c9 | ||
|
|
7adb6c8378 | ||
|
|
ec10e5c285 | ||
|
|
4dcd8641dc | ||
|
|
410f2fed12 | ||
|
|
0c43c116ee | ||
|
|
ec08cab62e | ||
|
|
b1c7a86a07 | ||
|
|
5334234ba5 | ||
|
|
45f6cf4fd9 | ||
|
|
cc66e0d5d9 | ||
|
|
c4eb56aa29 | ||
|
|
c714d7b53a | ||
|
|
97faed5b4c | ||
|
|
50dc4e142d | ||
|
|
8dda7a8ded | ||
|
|
84b3779af2 | ||
|
|
0aa12478b4 | ||
|
|
cf33fa2474 | ||
|
|
e26eeb438e | ||
|
|
dc30a395f4 | ||
|
|
9ad284a95a | ||
|
|
5020d30a30 | ||
|
|
bc4eb4220d | ||
|
|
20ec69b571 | ||
|
|
127bdfc782 | ||
|
|
b0ceac38cb | ||
|
|
1856271617 | ||
|
|
3f7eaf48e3 | ||
|
|
a4dd705db3 | ||
|
|
83ddc724bd |
@@ -25,7 +25,7 @@ dependencies {
|
|||||||
implementation "net.fabricmc:fabric-loader:${project.loader_version}"
|
implementation "net.fabricmc:fabric-loader:${project.loader_version}"
|
||||||
|
|
||||||
// Fabric API. This is technically optional, but you probably want it anyway.
|
// Fabric API. This is technically optional, but you probably want it anyway.
|
||||||
implementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
|
implementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,14 +7,14 @@ org.gradle.configuration-cache=false
|
|||||||
|
|
||||||
# Fabric Properties
|
# Fabric Properties
|
||||||
# check these on https://fabricmc.net/develop
|
# check these on https://fabricmc.net/develop
|
||||||
minecraft_version=26.1-snapshot-1
|
minecraft_version=26.1-snapshot-4
|
||||||
loader_version=0.18.3
|
loader_version=0.18.4
|
||||||
loom_version=1.14-SNAPSHOT
|
loom_version=1.15-SNAPSHOT
|
||||||
|
|
||||||
# Mod Properties
|
# Mod Properties
|
||||||
mod_version=0.0.0
|
mod_version=26.1.4
|
||||||
maven_group=de.jottyfan.minecraft
|
maven_group=de.jottyfan.minecraft
|
||||||
archives_base_name=quickly
|
archives_base_name=quickly
|
||||||
|
|
||||||
# Dependencies
|
# Dependencies
|
||||||
fabric_version=0.140.2+26.1
|
fabric_api_version=0.142.1+26.1
|
||||||
@@ -4,16 +4,13 @@ import org.apache.logging.log4j.LogManager;
|
|||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import de.jottyfan.minecraft.block.QuicklyBlocks;
|
import de.jottyfan.minecraft.block.QuicklyBlocks;
|
||||||
|
import de.jottyfan.minecraft.blockentity.QuicklyBlockEntity;
|
||||||
|
import de.jottyfan.minecraft.composter.QuicklyComposter;
|
||||||
|
import de.jottyfan.minecraft.event.QuicklyEvents;
|
||||||
import de.jottyfan.minecraft.feature.QuicklyFeatures;
|
import de.jottyfan.minecraft.feature.QuicklyFeatures;
|
||||||
import de.jottyfan.minecraft.item.QuicklyItems;
|
import de.jottyfan.minecraft.item.QuicklyItems;
|
||||||
|
import de.jottyfan.minecraft.loot.QuicklyLootTables;
|
||||||
import net.fabricmc.api.ModInitializer;
|
import net.fabricmc.api.ModInitializer;
|
||||||
import net.fabricmc.fabric.api.loot.v3.LootTableEvents;
|
|
||||||
import net.fabricmc.fabric.api.registry.CompostingChanceRegistry;
|
|
||||||
import net.minecraft.resources.Identifier;
|
|
||||||
import net.minecraft.world.level.storage.loot.LootPool;
|
|
||||||
import net.minecraft.world.level.storage.loot.entries.LootItem;
|
|
||||||
import net.minecraft.world.level.storage.loot.predicates.LootItemRandomChanceCondition;
|
|
||||||
import net.minecraft.world.level.storage.loot.providers.number.ConstantValue;
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author jotty
|
* @author jotty
|
||||||
@@ -24,39 +21,16 @@ public class Quickly implements ModInitializer {
|
|||||||
|
|
||||||
public static final Logger LOGGER = LogManager.getLogger(MOD_ID);
|
public static final Logger LOGGER = LogManager.getLogger(MOD_ID);
|
||||||
|
|
||||||
private void registerComposterItems() {
|
|
||||||
CompostingChanceRegistry.INSTANCE.add(QuicklyItems.COTTONSEED, 0.5f);
|
|
||||||
CompostingChanceRegistry.INSTANCE.add(QuicklyItems.COTTON, 0.75f);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void registerLootTableChanges() {
|
|
||||||
LootTableEvents.MODIFY.register((key, tableBuilder, source, registries) -> {
|
|
||||||
if (source.isBuiltin()) {
|
|
||||||
// TODO: maybe, better harvest cotton from dry grass instead?
|
|
||||||
Identifier shortGrass = Identifier.fromNamespaceAndPath("minecraft", "blocks/short_grass");
|
|
||||||
Identifier tallGrass = Identifier.fromNamespaceAndPath("minecraft", "blocks/tall_grass");
|
|
||||||
if (key.identifier().equals(shortGrass)) {
|
|
||||||
LootPool.Builder poolBuilder = LootPool.lootPool()
|
|
||||||
.setRolls(ConstantValue.exactly(1f))
|
|
||||||
.when(LootItemRandomChanceCondition.randomChance(0.1f))
|
|
||||||
.add(LootItem.lootTableItem(QuicklyItems.COTTONSEED));
|
|
||||||
tableBuilder.withPool(poolBuilder);
|
|
||||||
} else if (key.identifier().equals(tallGrass)) {
|
|
||||||
// for the canola loot table block later
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onInitialize() {
|
public void onInitialize() {
|
||||||
LOGGER.info("loading {}", MOD_ID);
|
LOGGER.info("loading {}", MOD_ID);
|
||||||
|
|
||||||
QuicklyItems.registerModItems();
|
QuicklyItems.registerModItems();
|
||||||
QuicklyBlocks.registerModBlocks();
|
QuicklyBlocks.registerModBlocks();
|
||||||
|
QuicklyBlockEntity.registerBlockEntities();
|
||||||
QuicklyFeatures.registerFeatures();
|
QuicklyFeatures.registerFeatures();
|
||||||
registerComposterItems();
|
QuicklyComposter.registerComposterItems();
|
||||||
registerLootTableChanges();
|
QuicklyLootTables.registerChanges();
|
||||||
|
QuicklyEvents.registerBlockBreak();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,6 @@
|
|||||||
package de.jottyfan.minecraft;
|
package de.jottyfan.minecraft;
|
||||||
|
|
||||||
import de.jottyfan.minecraft.block.QuicklyBlocks;
|
|
||||||
import net.fabricmc.api.ClientModInitializer;
|
import net.fabricmc.api.ClientModInitializer;
|
||||||
import net.fabricmc.fabric.api.client.rendering.v1.BlockRenderLayerMap;
|
|
||||||
import net.minecraft.client.renderer.chunk.ChunkSectionLayer;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -14,6 +11,5 @@ public class QuicklyClient implements ClientModInitializer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onInitializeClient() {
|
public void onInitializeClient() {
|
||||||
BlockRenderLayerMap.putBlock(QuicklyBlocks.COTTONPLANT, ChunkSectionLayer.CUTOUT);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
135
src/main/java/de/jottyfan/minecraft/block/BlockDrill.java
Normal file
135
src/main/java/de/jottyfan/minecraft/block/BlockDrill.java
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
package de.jottyfan.minecraft.block;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.jspecify.annotations.Nullable;
|
||||||
|
|
||||||
|
import com.mojang.serialization.MapCodec;
|
||||||
|
|
||||||
|
import de.jottyfan.minecraft.blockentity.DrillBlockEntity;
|
||||||
|
import de.jottyfan.minecraft.item.QuicklyItems;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.world.InteractionHand;
|
||||||
|
import net.minecraft.world.InteractionResult;
|
||||||
|
import net.minecraft.world.entity.item.ItemEntity;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
import net.minecraft.world.item.Item;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.Items;
|
||||||
|
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||||
|
import net.minecraft.world.level.BlockGetter;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.EntityBlock;
|
||||||
|
import net.minecraft.world.level.block.FallingBlock;
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
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 net.minecraft.world.level.block.state.StateDefinition.Builder;
|
||||||
|
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||||
|
import net.minecraft.world.level.block.state.properties.EnumProperty;
|
||||||
|
import net.minecraft.world.level.block.state.properties.IntegerProperty;
|
||||||
|
import net.minecraft.world.phys.BlockHitResult;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class BlockDrill extends FallingBlock implements EntityBlock {
|
||||||
|
public static final MapCodec<BlockDrill> CODEC = simpleCodec(BlockDrill::new);
|
||||||
|
|
||||||
|
private static final Integer MAX_FUEL = 255;
|
||||||
|
public static final IntegerProperty FUEL = IntegerProperty.create("fuel", 0, MAX_FUEL);
|
||||||
|
public static final EnumProperty<Direction> FACING = BlockStateProperties.FACING;
|
||||||
|
|
||||||
|
public BlockDrill(Properties properties) {
|
||||||
|
super(properties.strength(0.5f));
|
||||||
|
registerDefaultState(stateDefinition.any().setValue(FUEL, 0).setValue(FACING, Direction.DOWN));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void createBlockStateDefinition(Builder<Block, BlockState> builder) {
|
||||||
|
builder.add(FUEL, FACING);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockState getStateForPlacement(BlockPlaceContext context) {
|
||||||
|
return this.defaultBlockState().setValue(FACING, context.getNearestLookingDirection());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockEntity newBlockEntity(BlockPos pos, BlockState blockState) {
|
||||||
|
return new DrillBlockEntity(pos, blockState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T extends BlockEntity> @Nullable BlockEntityTicker<T> getTicker(Level level, BlockState blockState,
|
||||||
|
BlockEntityType<T> type) {
|
||||||
|
return (world1, pos, state1, be) -> DrillBlockEntity.tick(world1, pos, state1, be);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void spawnAfterBreak(BlockState state, ServerLevel level, BlockPos pos, ItemStack tool,
|
||||||
|
boolean dropExperience) {
|
||||||
|
Integer fuelLeft = state.getValue(FUEL) / 8; // 8 fuel is one bottle
|
||||||
|
level.addFreshEntity(
|
||||||
|
new ItemEntity(level, pos.getX(), pos.getY(), pos.getZ(), new ItemStack(QuicklyItems.CANOLABOTTLE, fuelLeft)));
|
||||||
|
level.addFreshEntity(new ItemEntity(level, pos.getX(), pos.getY(), pos.getZ(), new ItemStack(QuicklyBlocks.DRILL)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected InteractionResult useItemOn(ItemStack itemStack, BlockState state, Level level, BlockPos pos, Player player,
|
||||||
|
InteractionHand hand, BlockHitResult hitResult) {
|
||||||
|
Map<Item, Integer> loadings = new HashMap<>();
|
||||||
|
loadings.put(QuicklyItems.CANOLABOTTLE, 8);
|
||||||
|
loadings.put(QuicklyItems.CANOLABOTTLESTACK, 72);
|
||||||
|
Item item = itemStack.getItem();
|
||||||
|
if (QuicklyItems.MAGNIFIER.equals(item)) {
|
||||||
|
if (!level.isClientSide() && player instanceof ServerPlayer serverPlayer) {
|
||||||
|
serverPlayer.displayClientMessage(Component.translatable("info.block.drillfuel", state.getValue(FUEL)), true);
|
||||||
|
}
|
||||||
|
} else if (loadings.containsKey(item)) {
|
||||||
|
Integer fuelWeight = loadings.get(item);
|
||||||
|
if (fuelWeight != null) {
|
||||||
|
Integer load = MAX_FUEL - state.getValue(FUEL);
|
||||||
|
if (load < fuelWeight) {
|
||||||
|
fuelWeight = load;
|
||||||
|
}
|
||||||
|
level.setBlockAndUpdate(pos, state.setValue(FUEL, state.getValue(FUEL) + fuelWeight));
|
||||||
|
if (item.equals(QuicklyItems.CANOLABOTTLE)) {
|
||||||
|
level.addFreshEntity(
|
||||||
|
new ItemEntity(level, pos.getX(), pos.getY(), pos.getZ(), new ItemStack(Items.GLASS_BOTTLE, 1)));
|
||||||
|
} else if (item.equals(QuicklyItems.CANOLABOTTLESTACK)) {
|
||||||
|
level.addFreshEntity(
|
||||||
|
new ItemEntity(level, pos.getX(), pos.getY(), pos.getZ(), new ItemStack(Items.GLASS_BOTTLE, 9)));
|
||||||
|
}
|
||||||
|
player.getActiveItem().shrink(1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Direction newDirection = hitResult.getDirection();
|
||||||
|
newDirection = newDirection.equals(Direction.UP) ? Direction.DOWN : newDirection;
|
||||||
|
Integer fuelLeft = state.getValue(FUEL);
|
||||||
|
level.addFreshEntity(
|
||||||
|
new ItemEntity(level, pos.getX(), pos.getY(), pos.getZ(), new ItemStack(QuicklyItems.CANOLABOTTLE, fuelLeft)));
|
||||||
|
level.setBlockAndUpdate(pos, QuicklyBlocks.DRILL.defaultBlockState().setValue(FACING, newDirection));
|
||||||
|
}
|
||||||
|
return InteractionResult.SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected MapCodec<? extends FallingBlock> codec() {
|
||||||
|
return CODEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDustColor(BlockState blockState, BlockGetter level, BlockPos pos) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
35
src/main/java/de/jottyfan/minecraft/block/BlockDrops.java
Normal file
35
src/main/java/de/jottyfan/minecraft/block/BlockDrops.java
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
package de.jottyfan.minecraft.block;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import de.jottyfan.minecraft.item.QuicklyItems;
|
||||||
|
import net.minecraft.resources.Identifier;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.storage.loot.LootParams.Builder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class BlockDrops extends Block {
|
||||||
|
|
||||||
|
private Identifier dropItem;
|
||||||
|
private Integer count;
|
||||||
|
|
||||||
|
public BlockDrops(Properties properties, Identifier dropItem, Integer count) {
|
||||||
|
super(properties);
|
||||||
|
this.dropItem = dropItem;
|
||||||
|
this.count = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<ItemStack> getDrops(BlockState state, Builder builder) {
|
||||||
|
ItemStack droppable = count == null || count < 1 || dropItem == null ? new ItemStack(this.asItem())
|
||||||
|
: new ItemStack(QuicklyItems.of(dropItem), count);
|
||||||
|
return Arrays.asList(new ItemStack[] { droppable });
|
||||||
|
}
|
||||||
|
}
|
||||||
61
src/main/java/de/jottyfan/minecraft/block/BlockOre.java
Normal file
61
src/main/java/de/jottyfan/minecraft/block/BlockOre.java
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
package de.jottyfan.minecraft.block;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import de.jottyfan.minecraft.item.QuicklyItems;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.resources.Identifier;
|
||||||
|
import net.minecraft.sounds.SoundEvent;
|
||||||
|
import net.minecraft.sounds.SoundSource;
|
||||||
|
import net.minecraft.world.entity.projectile.Projectile;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.storage.loot.LootParams.Builder;
|
||||||
|
import net.minecraft.world.phys.BlockHitResult;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class BlockOre extends Block {
|
||||||
|
|
||||||
|
private SoundEvent soundEvent;
|
||||||
|
private Identifier[] dropItems;
|
||||||
|
|
||||||
|
public BlockOre(Properties properties, Identifier... dropItems) {
|
||||||
|
super(properties.requiresCorrectToolForDrops());
|
||||||
|
this.dropItems = dropItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockOre(Properties properties, SoundEvent soundEvent, Identifier... dropItems) {
|
||||||
|
super(properties.requiresCorrectToolForDrops());
|
||||||
|
this.soundEvent = soundEvent;
|
||||||
|
this.dropItems = dropItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<ItemStack> getDrops(BlockState state, Builder builder) {
|
||||||
|
List<ItemStack> list = new ArrayList<>();
|
||||||
|
if (dropItems == null || dropItems.length < 1) {
|
||||||
|
list.add(new ItemStack(state.getBlock().asItem()));
|
||||||
|
} else {
|
||||||
|
for (Identifier identifier : dropItems) {
|
||||||
|
list.add(new ItemStack(QuicklyItems.of(identifier)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onProjectileHit(final Level level, final BlockState state, final BlockHitResult hitResult,
|
||||||
|
final Projectile projectile) {
|
||||||
|
if (!level.isClientSide() && soundEvent != null) {
|
||||||
|
BlockPos hitPos = hitResult.getBlockPos();
|
||||||
|
level.playSound(null, hitPos, soundEvent, SoundSource.BLOCKS, 1.0F, 0.5F + level.getRandom().nextFloat() * 1.2F);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
package de.jottyfan.minecraft.block;
|
|
||||||
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import de.jottyfan.minecraft.item.QuicklyItems;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
|
||||||
import net.minecraft.world.level.storage.loot.LootParams.Builder;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author jotty
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class BlockOreDeepslateTurquoise extends BlockOreTurquoise {
|
|
||||||
|
|
||||||
public BlockOreDeepslateTurquoise(Properties properties) {
|
|
||||||
super(properties);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected List<ItemStack> getDrops(BlockState state, Builder builder) {
|
|
||||||
return Arrays.asList(new ItemStack[] { new ItemStack(QuicklyItems.RAWTURQUOISE, 2) });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
package de.jottyfan.minecraft.block;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import de.jottyfan.minecraft.item.QuicklyItems;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
import net.minecraft.world.level.block.AmethystBlock;
|
|
||||||
import net.minecraft.world.level.block.SoundType;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
|
||||||
import net.minecraft.world.level.storage.loot.LootParams.Builder;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author jotty
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class BlockOreTurquoise extends AmethystBlock {
|
|
||||||
|
|
||||||
public BlockOreTurquoise(Properties properties) {
|
|
||||||
super(properties.strength(3.0f).sound(SoundType.AMETHYST).requiresCorrectToolForDrops());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected List<ItemStack> getDrops(BlockState state, Builder builder) {
|
|
||||||
return Arrays.asList(new ItemStack[] { new ItemStack(QuicklyItems.RAWTURQUOISE) });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +1,21 @@
|
|||||||
package de.jottyfan.minecraft.block;
|
package de.jottyfan.minecraft.block;
|
||||||
|
|
||||||
import de.jottyfan.minecraft.Quickly;
|
import de.jottyfan.minecraft.item.QuicklyItems;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.registries.BuiltInRegistries;
|
|
||||||
import net.minecraft.resources.Identifier;
|
import net.minecraft.resources.Identifier;
|
||||||
import net.minecraft.world.Containers;
|
import net.minecraft.world.Containers;
|
||||||
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.item.Item;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.level.BlockGetter;
|
||||||
|
import net.minecraft.world.level.ItemLike;
|
||||||
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.CropBlock;
|
import net.minecraft.world.level.block.CropBlock;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.phys.BlockHitResult;
|
import net.minecraft.world.phys.BlockHitResult;
|
||||||
|
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||||
|
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -21,21 +24,36 @@ import net.minecraft.world.phys.BlockHitResult;
|
|||||||
*/
|
*/
|
||||||
public class BlockPlant extends CropBlock {
|
public class BlockPlant extends CropBlock {
|
||||||
|
|
||||||
private String seedName;
|
private Identifier seedName;
|
||||||
private String fruitName;
|
private Identifier fruitName;
|
||||||
|
|
||||||
public BlockPlant(Properties properties, String seedName, String fruitName) {
|
public BlockPlant(Properties properties, Identifier seedName, Identifier fruitName) {
|
||||||
super(properties);
|
super(properties.noOcclusion().dynamicShape());
|
||||||
this.seedName = seedName;
|
this.seedName = seedName;
|
||||||
this.fruitName = fruitName;
|
this.fruitName = fruitName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Item getSeed() {
|
@Override
|
||||||
return BuiltInRegistries.ITEM.getValue(Identifier.fromNamespaceAndPath(Quickly.MOD_ID, seedName));
|
protected VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) {
|
||||||
|
return Block.box(2.0D, 0.0D, 2.0D, 14.0D, 13.0D, 14.0D);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Item getFruit() {
|
@Override
|
||||||
return BuiltInRegistries.ITEM.getValue(Identifier.fromNamespaceAndPath(Quickly.MOD_ID, fruitName));
|
protected float getShadeBrightness(BlockState state, BlockGetter level, BlockPos pos) {
|
||||||
|
return 1.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean propagatesSkylightDown(BlockState state) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemLike getSeed() {
|
||||||
|
return QuicklyItems.of(seedName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemLike getFruit() {
|
||||||
|
return QuicklyItems.of(fruitName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
84
src/main/java/de/jottyfan/minecraft/block/BlockStacker.java
Normal file
84
src/main/java/de/jottyfan/minecraft/block/BlockStacker.java
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
package de.jottyfan.minecraft.block;
|
||||||
|
|
||||||
|
import org.jspecify.annotations.Nullable;
|
||||||
|
|
||||||
|
import com.mojang.serialization.MapCodec;
|
||||||
|
|
||||||
|
import de.jottyfan.minecraft.blockentity.BlockStackerEntity;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.EntityBlock;
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
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 net.minecraft.world.level.block.state.StateDefinition.Builder;
|
||||||
|
import net.minecraft.world.level.block.state.properties.EnumProperty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class BlockStacker extends Block implements EntityBlock {
|
||||||
|
public static final MapCodec<BlockStacker> CODEC = simpleCodec(BlockStacker::new);
|
||||||
|
|
||||||
|
public static final EnumProperty<Direction> SOURCE = EnumProperty.create("source", Direction.class, Direction.NORTH,
|
||||||
|
Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN);
|
||||||
|
public static final EnumProperty<Direction> DEST = EnumProperty.create("dest", Direction.class, Direction.NORTH,
|
||||||
|
Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.UP, Direction.DOWN);
|
||||||
|
|
||||||
|
public BlockStacker(Properties properties) {
|
||||||
|
super(properties);
|
||||||
|
registerDefaultState(stateDefinition.any().setValue(SOURCE, Direction.UP).setValue(DEST, Direction.DOWN));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void createBlockStateDefinition(Builder<Block, BlockState> builder) {
|
||||||
|
builder.add(SOURCE, DEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockState getStateForPlacement(BlockPlaceContext context) {
|
||||||
|
return this.defaultBlockState().setValue(SOURCE, context.getNearestLookingDirection()).setValue(DEST, context.getNearestLookingDirection().getOpposite());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T extends BlockEntity> @Nullable BlockEntityTicker<T> getTicker(Level level, BlockState blockState,
|
||||||
|
BlockEntityType<T> type) {
|
||||||
|
return (lambdaLevel, pos, state, blockEntity) -> BlockStackerEntity.tick(lambdaLevel, pos, state, blockEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable BlockEntity newBlockEntity(BlockPos pos, BlockState blockState) {
|
||||||
|
return new BlockStackerEntity(pos, blockState);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MapCodec<BlockStacker> getCodec() {
|
||||||
|
return CODEC;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Direction getSource(BlockState state) {
|
||||||
|
return state.getValue(SOURCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Direction getDest(BlockState state) {
|
||||||
|
return state.getValue(DEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockPos getOffset(BlockState state, EnumProperty<Direction> sourceOrDest) {
|
||||||
|
BlockPos pos = new BlockPos(0, 0, 0);
|
||||||
|
return switch (state.getValue(sourceOrDest)) {
|
||||||
|
case Direction.UP -> pos.above();
|
||||||
|
case Direction.DOWN -> pos.below();
|
||||||
|
case Direction.NORTH -> pos.north();
|
||||||
|
case Direction.EAST -> pos.east();
|
||||||
|
case Direction.SOUTH -> pos.south();
|
||||||
|
case Direction.WEST -> pos.west();
|
||||||
|
default -> pos;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
92
src/main/java/de/jottyfan/minecraft/block/Itemhoarder.java
Normal file
92
src/main/java/de/jottyfan/minecraft/block/Itemhoarder.java
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
package de.jottyfan.minecraft.block;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.jspecify.annotations.Nullable;
|
||||||
|
|
||||||
|
import de.jottyfan.minecraft.blockentity.ItemHoarderBlockEntity;
|
||||||
|
import de.jottyfan.minecraft.item.QuicklyItems;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.network.chat.MutableComponent;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.world.InteractionHand;
|
||||||
|
import net.minecraft.world.InteractionResult;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.EntityBlock;
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
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 net.minecraft.world.level.storage.loot.LootParams.Builder;
|
||||||
|
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
||||||
|
import net.minecraft.world.phys.BlockHitResult;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Itemhoarder extends Block implements EntityBlock {
|
||||||
|
|
||||||
|
public Itemhoarder(Properties properties) {
|
||||||
|
super(properties.strength(2.5f));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable BlockEntity newBlockEntity(BlockPos pos, BlockState blockState) {
|
||||||
|
return new ItemHoarderBlockEntity(pos, blockState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(Level level, BlockState state,
|
||||||
|
BlockEntityType<T> type) {
|
||||||
|
return level.isClientSide() ? null : (lvl, pos, st, be) -> {
|
||||||
|
if (be instanceof ItemHoarderBlockEntity ihbe) {
|
||||||
|
ItemHoarderBlockEntity.tick(lvl, pos, st, ihbe);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected InteractionResult useItemOn(ItemStack itemStack, BlockState state, Level level, BlockPos pos, Player player,
|
||||||
|
InteractionHand hand, BlockHitResult hitResult) {
|
||||||
|
if (player instanceof ServerPlayer serverPlayer) {
|
||||||
|
if (QuicklyItems.MAGNIFIER.equals(itemStack.getItem())) {
|
||||||
|
MutableComponent message = Component.empty();
|
||||||
|
BlockEntity blockEntity = level.getBlockEntity(pos);
|
||||||
|
if (blockEntity instanceof ItemHoarderBlockEntity) {
|
||||||
|
ItemHoarderBlockEntity ihbe = (ItemHoarderBlockEntity) blockEntity;
|
||||||
|
for (ItemStack stack : ihbe.getStacks().values()) {
|
||||||
|
MutableComponent line = Component.literal(stack.getCount() + "x ").append(stack.getHoverName());
|
||||||
|
message.append(Component.literal("\n")).append(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Component complete = Component.translatable("info.block.itemhoarder", message);
|
||||||
|
serverPlayer.displayClientMessage(complete, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return InteractionResult.SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<ItemStack> getDrops(BlockState state, Builder builder) {
|
||||||
|
List<ItemStack> list = new ArrayList<>();
|
||||||
|
list.add(new ItemStack(QuicklyBlocks.ITEMHOARDER));
|
||||||
|
|
||||||
|
BlockEntity blockEntity = builder.getOptionalParameter(LootContextParams.BLOCK_ENTITY);
|
||||||
|
if (blockEntity instanceof ItemHoarderBlockEntity) {
|
||||||
|
ItemHoarderBlockEntity ihbe = (ItemHoarderBlockEntity) blockEntity;
|
||||||
|
for (ItemStack stack : ihbe.getStacks().values()) {
|
||||||
|
list.add(stack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
213
src/main/java/de/jottyfan/minecraft/block/Lavahoarder.java
Normal file
213
src/main/java/de/jottyfan/minecraft/block/Lavahoarder.java
Normal file
@@ -0,0 +1,213 @@
|
|||||||
|
package de.jottyfan.minecraft.block;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import de.jottyfan.minecraft.item.QuicklyItems;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.util.RandomSource;
|
||||||
|
import net.minecraft.world.InteractionHand;
|
||||||
|
import net.minecraft.world.InteractionResult;
|
||||||
|
import net.minecraft.world.entity.item.ItemEntity;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.Items;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.Blocks;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.block.state.StateDefinition;
|
||||||
|
import net.minecraft.world.level.block.state.properties.BooleanProperty;
|
||||||
|
import net.minecraft.world.level.storage.loot.LootParams.Builder;
|
||||||
|
import net.minecraft.world.phys.BlockHitResult;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Lavahoarder extends Block {
|
||||||
|
|
||||||
|
public static final BooleanProperty FILLED = BooleanProperty.create("filled");
|
||||||
|
|
||||||
|
public Lavahoarder(Properties properties) {
|
||||||
|
super(properties);
|
||||||
|
registerDefaultState(stateDefinition.any().setValue(FILLED, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
|
||||||
|
builder.add(FILLED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<ItemStack> getDrops(BlockState state, Builder params) {
|
||||||
|
List<ItemStack> list = new ArrayList<>();
|
||||||
|
list.add(new ItemStack(QuicklyBlocks.LAVAHOARDER));
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final void spawnRandomItems(Level level, BlockPos pos, Integer count) {
|
||||||
|
Integer which = level.getRandom().nextInt(10);
|
||||||
|
ItemStack stack = null;
|
||||||
|
if (which < 1) {
|
||||||
|
stack = new ItemStack(Items.DIAMOND, level.getRandom().nextInt(count + 2));
|
||||||
|
} else if (which < 2) {
|
||||||
|
stack = new ItemStack(Items.EMERALD, level.getRandom().nextInt(count + 1));
|
||||||
|
} else if (which < 3) {
|
||||||
|
stack = new ItemStack(Items.RAW_GOLD, level.getRandom().nextInt(count));
|
||||||
|
} else if (which < 4) {
|
||||||
|
stack = new ItemStack(Items.RAW_IRON, level.getRandom().nextInt(count + 1));
|
||||||
|
} else if (which < 5) {
|
||||||
|
stack = new ItemStack(Items.RAW_COPPER, level.getRandom().nextInt(count + 2));
|
||||||
|
} else if (which < 6) {
|
||||||
|
stack = new ItemStack(Items.OBSIDIAN);
|
||||||
|
} else if (which < 7) {
|
||||||
|
stack = new ItemStack(Items.LAPIS_LAZULI);
|
||||||
|
} else if (which < 8) {
|
||||||
|
stack = new ItemStack(QuicklyItems.RAWTURQUOISE);
|
||||||
|
} else if (which < 9) {
|
||||||
|
stack = new ItemStack(QuicklyItems.SULFOR);
|
||||||
|
}
|
||||||
|
if (stack != null) {
|
||||||
|
level.addFreshEntity(new ItemEntity(level, pos.getX(), pos.getY(), pos.getZ(), stack));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sucks the lava that touches the block
|
||||||
|
*
|
||||||
|
* @param world the world
|
||||||
|
* @param pos the pos
|
||||||
|
* @return true if lava was found
|
||||||
|
*/
|
||||||
|
public static final boolean suckLava(ServerLevel level, BlockPos pos) {
|
||||||
|
if (level == null) {
|
||||||
|
return false;
|
||||||
|
} else if (Blocks.LAVA.equals(level.getBlockState(pos).getBlock())) {
|
||||||
|
level.setBlock(pos, Blocks.AIR.defaultBlockState(), 2);
|
||||||
|
if (new Random().nextFloat() > 0.9f) {
|
||||||
|
spawnRandomItems(level, pos.above(), 2);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) {
|
||||||
|
boolean any = false;
|
||||||
|
any = any || suckLava(level, pos.north());
|
||||||
|
any = any || suckLava(level, pos.south());
|
||||||
|
any = any || suckLava(level, pos.east());
|
||||||
|
any = any || suckLava(level, pos.west());
|
||||||
|
any = any || suckLava(level, pos.above());
|
||||||
|
any = any || suckLava(level, pos.below());
|
||||||
|
if (any && !level.getBlockState(pos).getValue(Lavahoarder.FILLED)) {
|
||||||
|
level.setBlockAndUpdate(pos, QuicklyBlocks.LAVAHOARDER.defaultBlockState().setValue(Lavahoarder.FILLED, true));
|
||||||
|
}
|
||||||
|
level.scheduleTick(pos, this, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player,
|
||||||
|
BlockHitResult hitResult) {
|
||||||
|
if (!level.isClientSide()) {
|
||||||
|
ItemStack handStack = player.getMainHandItem();
|
||||||
|
if (handStack != null && Items.BUCKET.equals(handStack.getItem())) {
|
||||||
|
Integer amount = handStack.getCount();
|
||||||
|
ItemStack lavaBucketStack = new ItemStack(Items.LAVA_BUCKET, 1);
|
||||||
|
ItemStack emptyBucketStack = new ItemStack(Items.BUCKET, amount - 1);
|
||||||
|
if (emptyBucketStack.getCount() < 1) {
|
||||||
|
player.setItemInHand(InteractionHand.MAIN_HAND, lavaBucketStack);
|
||||||
|
} else {
|
||||||
|
player.setItemInHand(InteractionHand.MAIN_HAND, emptyBucketStack);
|
||||||
|
level.addFreshEntity(new ItemEntity(level, pos.getX(), pos.getY(), pos.getZ(), lavaBucketStack));
|
||||||
|
}
|
||||||
|
spawnRandomItems(level, pos, 2);
|
||||||
|
level.setBlockAndUpdate(pos, QuicklyBlocks.LAVAHOARDER.defaultBlockState()); // sets filled = false
|
||||||
|
level.scheduleTick(pos, this, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return InteractionResult.SUCCESS; // forbid to empty the just filled lava bucket
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String stringOf(BlockPos pos) {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
buf.append(pos.getX()).append(":");
|
||||||
|
buf.append(pos.getY()).append(":");
|
||||||
|
buf.append(pos.getZ());
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void findAllAttachedLavaBlocks(Set<String> list, BlockPos pos, Level level, Integer counter) {
|
||||||
|
if (counter < 1) {
|
||||||
|
return;
|
||||||
|
} else if (Blocks.LAVA.equals(level.getBlockState(pos).getBlock())) {
|
||||||
|
String p = stringOf(pos);
|
||||||
|
if (!list.contains(p)) {
|
||||||
|
list.add(p);
|
||||||
|
findAllAttachedLavaBlocks(list, pos.above(), level, counter - 1);
|
||||||
|
findAllAttachedLavaBlocks(list, pos.below(), level, counter - 1);
|
||||||
|
findAllAttachedLavaBlocks(list, pos.north(), level, counter - 1);
|
||||||
|
findAllAttachedLavaBlocks(list, pos.south(), level, counter - 1);
|
||||||
|
findAllAttachedLavaBlocks(list, pos.east(), level, counter - 1);
|
||||||
|
findAllAttachedLavaBlocks(list, pos.west(), level, counter - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final BlockPos blockPosOf(String s) {
|
||||||
|
if (s.contains(":")) {
|
||||||
|
String[] parts = s.split(":");
|
||||||
|
if (parts.length > 2) {
|
||||||
|
Integer x = Integer.valueOf(parts[0]);
|
||||||
|
Integer y = Integer.valueOf(parts[1]);
|
||||||
|
Integer z = Integer.valueOf(parts[2]);
|
||||||
|
return new BlockPos(x, y, z);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean movedByPiston) {
|
||||||
|
Set<String> positions = new HashSet<>();
|
||||||
|
Integer counter = 8; // TODO: make it level up - able
|
||||||
|
findAllAttachedLavaBlocks(positions, pos.above(), level, counter);
|
||||||
|
findAllAttachedLavaBlocks(positions, pos.below(), level, counter);
|
||||||
|
findAllAttachedLavaBlocks(positions, pos.north(), level, counter);
|
||||||
|
findAllAttachedLavaBlocks(positions, pos.south(), level, counter);
|
||||||
|
findAllAttachedLavaBlocks(positions, pos.east(), level, counter);
|
||||||
|
findAllAttachedLavaBlocks(positions, pos.west(), level, counter);
|
||||||
|
Integer amount = positions.size();
|
||||||
|
for (String p : positions) {
|
||||||
|
level.setBlockAndUpdate(blockPosOf(p), Blocks.AIR.defaultBlockState());
|
||||||
|
}
|
||||||
|
if (amount > 0) {
|
||||||
|
if (!level.getBlockState(pos).getValue(Lavahoarder.FILLED)) {
|
||||||
|
level.setBlockAndUpdate(pos, QuicklyBlocks.LAVAHOARDER.defaultBlockState().setValue(FILLED, true));
|
||||||
|
}
|
||||||
|
level.scheduleTick(pos, QuicklyBlocks.LAVAHOARDER, 1);
|
||||||
|
int count = 0;
|
||||||
|
Random random = new Random();
|
||||||
|
for (int i = 0; i < amount; i++) {
|
||||||
|
if (random.nextFloat() < 0.0125) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (count > 0) {
|
||||||
|
Lavahoarder.spawnRandomItems(level, pos.above(), count);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
level.scheduleTick(pos, this, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
109
src/main/java/de/jottyfan/minecraft/block/Monsterhoarder.java
Normal file
109
src/main/java/de/jottyfan/minecraft/block/Monsterhoarder.java
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
package de.jottyfan.minecraft.block;
|
||||||
|
|
||||||
|
import org.jspecify.annotations.Nullable;
|
||||||
|
|
||||||
|
import de.jottyfan.minecraft.item.QuicklyItems;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.network.chat.Component;
|
||||||
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
import net.minecraft.sounds.SoundEvents;
|
||||||
|
import net.minecraft.sounds.SoundSource;
|
||||||
|
import net.minecraft.util.RandomSource;
|
||||||
|
import net.minecraft.world.InteractionHand;
|
||||||
|
import net.minecraft.world.InteractionResult;
|
||||||
|
import net.minecraft.world.entity.LivingEntity;
|
||||||
|
import net.minecraft.world.entity.monster.Monster;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.Items;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.block.state.StateDefinition.Builder;
|
||||||
|
import net.minecraft.world.level.block.state.properties.IntegerProperty;
|
||||||
|
import net.minecraft.world.phys.AABB;
|
||||||
|
import net.minecraft.world.phys.BlockHitResult;
|
||||||
|
import net.minecraft.world.ticks.ScheduledTick;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Monsterhoarder extends Block {
|
||||||
|
|
||||||
|
private static final Integer MINSUCKRADIUS = 2;
|
||||||
|
private static final Integer MAXSUCKRADIUS = 20;
|
||||||
|
private static final Integer MINBURNTICKS = 10;
|
||||||
|
private static final Integer MAXBURNTICKS = 200;
|
||||||
|
private static final IntegerProperty SUCKRADIUS = IntegerProperty.create("suckradius", MINSUCKRADIUS, MAXSUCKRADIUS);
|
||||||
|
private static final IntegerProperty BURNTICKS = IntegerProperty.create("burnticks", MINBURNTICKS, MAXBURNTICKS);
|
||||||
|
|
||||||
|
public Monsterhoarder(Properties properties) {
|
||||||
|
super(properties.strength(2.5f).lightLevel(state -> state.getValue(SUCKRADIUS)));
|
||||||
|
registerDefaultState(stateDefinition.any().setValue(SUCKRADIUS, MINSUCKRADIUS).setValue(BURNTICKS, MINBURNTICKS));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void createBlockStateDefinition(Builder<Block, BlockState> builder) {
|
||||||
|
builder.add(SUCKRADIUS, BURNTICKS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected InteractionResult useItemOn(ItemStack itemStack, BlockState state, Level level, BlockPos pos, Player player,
|
||||||
|
InteractionHand hand, BlockHitResult hitResult) {
|
||||||
|
if (Items.WATER_BUCKET.equals(itemStack.getItem())) {
|
||||||
|
level.setBlock(pos, state.setValue(SUCKRADIUS, MINSUCKRADIUS), UPDATE_ALL);
|
||||||
|
player.setItemInHand(hand, new ItemStack(Items.BUCKET));
|
||||||
|
} else if (Items.TORCH.equals(itemStack.getItem())) {
|
||||||
|
level.setBlock(pos, state.cycle(SUCKRADIUS), UPDATE_ALL);
|
||||||
|
itemStack.shrink(1);
|
||||||
|
} else if (Items.SOUL_TORCH.equals(itemStack.getItem())) {
|
||||||
|
int newBurnTicks = state.getValue(BURNTICKS) + 10;
|
||||||
|
newBurnTicks = newBurnTicks < MAXBURNTICKS ? newBurnTicks : MAXBURNTICKS;
|
||||||
|
level.setBlock(pos, state.setValue(BURNTICKS, newBurnTicks), UPDATE_ALL);
|
||||||
|
itemStack.shrink(1);
|
||||||
|
} else if (Items.REDSTONE_TORCH.equals(itemStack.getItem())) {
|
||||||
|
level.setBlock(pos, state.cycle(SUCKRADIUS), UPDATE_ALL);
|
||||||
|
} else if (Items.COPPER_TORCH.equals(itemStack.getItem())) {
|
||||||
|
level.setBlock(pos, state.setValue(BURNTICKS, MINBURNTICKS), UPDATE_ALL);
|
||||||
|
itemStack.shrink(1);
|
||||||
|
} else if (QuicklyItems.MAGNIFIER.equals(itemStack.getItem())) {
|
||||||
|
int suckRadius = state.getValue(SUCKRADIUS);
|
||||||
|
int burnTicks = state.getValue(BURNTICKS);
|
||||||
|
Component message = Component.translatable("info.block.monsterhoarder", suckRadius, burnTicks);
|
||||||
|
if (player instanceof ServerPlayer serverPlayer) {
|
||||||
|
serverPlayer.displayClientMessage(message, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return InteractionResult.SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) {
|
||||||
|
if (!level.isClientSide()) {
|
||||||
|
AABB checkArea = new AABB(pos).inflate(state.getValue(SUCKRADIUS));
|
||||||
|
for (Monster monster : level.getEntitiesOfClass(Monster.class, checkArea)) {
|
||||||
|
if (monster.fireImmune()) {
|
||||||
|
monster.kill(level);
|
||||||
|
} else {
|
||||||
|
monster.igniteForTicks(state.getValue(BURNTICKS));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (level instanceof ServerLevel serverLevel) {
|
||||||
|
serverLevel.getBlockTicks()
|
||||||
|
.schedule(new ScheduledTick<>(this, pos, level.getGameTime() + 20, 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPlacedBy(Level level, BlockPos pos, BlockState state, @Nullable LivingEntity by, ItemStack itemStack) {
|
||||||
|
if (level instanceof ServerLevel serverLevel) {
|
||||||
|
serverLevel.getBlockTicks()
|
||||||
|
.schedule(new ScheduledTick<>(this, pos, level.getGameTime() + 20, 1));
|
||||||
|
level.playSound(null, pos, SoundEvents.UI_TOAST_CHALLENGE_COMPLETE, SoundSource.PLAYERS, 1f, 1f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,14 +3,14 @@ package de.jottyfan.minecraft.block;
|
|||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
import de.jottyfan.minecraft.Quickly;
|
import de.jottyfan.minecraft.Quickly;
|
||||||
import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents;
|
import de.jottyfan.minecraft.name.ID;
|
||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
import net.minecraft.core.registries.BuiltInRegistries;
|
import net.minecraft.core.registries.BuiltInRegistries;
|
||||||
import net.minecraft.core.registries.Registries;
|
import net.minecraft.core.registries.Registries;
|
||||||
import net.minecraft.resources.Identifier;
|
import net.minecraft.resources.Identifier;
|
||||||
import net.minecraft.resources.ResourceKey;
|
import net.minecraft.resources.ResourceKey;
|
||||||
|
import net.minecraft.sounds.SoundEvents;
|
||||||
import net.minecraft.world.item.BlockItem;
|
import net.minecraft.world.item.BlockItem;
|
||||||
import net.minecraft.world.item.CreativeModeTabs;
|
|
||||||
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.minecraft.world.level.block.Blocks;
|
import net.minecraft.world.level.block.Blocks;
|
||||||
@@ -23,25 +23,63 @@ import net.minecraft.world.level.block.state.BlockBehaviour.Properties;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class QuicklyBlocks {
|
public class QuicklyBlocks {
|
||||||
public static final Block KELPBUNDLE = registerBlock("kelpbundle",
|
public static final Block KELPBUNDLE = registerBlock(ID.KELPBUNDLE,
|
||||||
Properties.of().instabreak().sound(SoundType.WET_GRASS).strength(0.1f).friction(0.95f));
|
Properties.of().instabreak().sound(SoundType.WET_GRASS).strength(0.1f).friction(0.95f));
|
||||||
public static final Block TURQUOISEBLOCK = registerBlock("blockturquoise", Properties.of().strength(1.5f));
|
public static final Block TURQUOISEBLOCK = registerBlock(ID.BLOCKTURQUOISE, Properties.of().strength(1.5f));
|
||||||
public static final Block ORETURQUOISE = registerBlock("oreturquoise", p -> new BlockOreTurquoise(p));
|
public static final Block ORETURQUOISE = registerBlock(ID.ORETURQUOISE,
|
||||||
public static final Block OREDEEPSLATETURQUOISE = registerBlock("oredeepslateturquoise",
|
properties -> new BlockOre(properties.strength(3.0f).sound(SoundType.AMETHYST), SoundEvents.AMETHYST_BLOCK_CHIME,
|
||||||
p -> new BlockOreDeepslateTurquoise(p));
|
ID.RAWTURQUOISE));
|
||||||
public static final Block COTTONPLANT = registerBlock("blockcottonplant", Properties.ofFullCopy(Blocks.WHEAT),
|
public static final Block OREDEEPSLATETURQUOISE = registerBlock(ID.OREDEEPSLATETURQUOISE,
|
||||||
p -> new BlockPlant(p, "cottonseed", "cotton"));
|
properties -> new BlockOre(properties, SoundEvents.AMETHYST_BLOCK_CHIME, ID.RAWTURQUOISE));
|
||||||
|
public static final Block COTTONPLANT = registerBlock(ID.BLOCKCOTTONPLANT, Properties.ofFullCopy(Blocks.WHEAT),
|
||||||
|
properties -> new BlockPlant(properties, ID.COTTONSEED, ID.COTTON));
|
||||||
|
public static final Block CANOLAPLANT = registerBlock(ID.BLOCKCANOLAPLANT, Properties.ofFullCopy(Blocks.WHEAT),
|
||||||
|
properties -> new BlockPlant(properties, ID.CANOLASEED, ID.CANOLA));
|
||||||
|
public static final Block LAVAHOARDER = registerBlock(ID.LAVAHOARDER,
|
||||||
|
Properties.of().strength(2.5f).lightLevel(state -> state.getValue(Lavahoarder.FILLED) ? 15 : 0),
|
||||||
|
Lavahoarder::new);
|
||||||
|
public static final Block QUICKIEPOWDER = registerBlock(ID.BLOCKQUICKIEPOWDER,
|
||||||
|
properties -> new BlockDrops(properties, ID.QUICKIEPOWDER, 9));
|
||||||
|
public static final Block SPEEDPOWDER = registerBlock(ID.BLOCKSPEEDPOWDER,
|
||||||
|
properties -> new BlockDrops(properties, ID.SPEEDPOWDER, 9));
|
||||||
|
public static final Block MONSTERHOARDER = registerBlock(ID.MONSTERHOARDER, Monsterhoarder::new);
|
||||||
|
public static final Block ITEMHOARDER = registerBlock(ID.ITEMHOARDER, Itemhoarder::new);
|
||||||
|
public static final Block DRILL = registerBlock(ID.DRILL, BlockDrill::new);
|
||||||
|
public static final Block STACKER = registerBlock(ID.BLOCKSTACKER,
|
||||||
|
properties -> new BlockStacker(properties.strength(2.5f)));
|
||||||
|
public static final Block DIRTSALPETER = registerBlock(ID.DIRTSALPETER,
|
||||||
|
properties -> new BlockOre(properties.strength(2.2f), ID.SALPETER));
|
||||||
|
public static final Block SANDSALPETER = registerBlock(ID.SANDSALPETER,
|
||||||
|
properties -> new BlockOre(properties.strength(1.5f), ID.SALPETER));
|
||||||
|
public static final Block OREDEEPSLATESULFOR = registerBlock(ID.OREDEEPSLATESULFOR,
|
||||||
|
properties -> new BlockOre(properties.strength(2.0f), ID.SULFOR));
|
||||||
|
public static final Block ORENETHERSULFOR = registerBlock(ID.ORENETHERSULFOR,
|
||||||
|
properties -> new BlockOre(properties.strength(2.0f), ID.SULFOR));
|
||||||
|
public static final Block ORESALPETER = registerBlock(ID.ORESALPETER,
|
||||||
|
properties -> new BlockOre(properties.strength(1.9f), ID.SALPETER));
|
||||||
|
public static final Block ORESANDSALPETER = registerBlock(ID.ORESANDSALPETER,
|
||||||
|
properties -> new BlockOre(properties.strength(1.5f), ID.SALPETER));
|
||||||
|
public static final Block ORESULFOR = registerBlock(ID.ORESULFOR,
|
||||||
|
properties -> new BlockOre(properties.strength(1.9f), ID.SULFOR));
|
||||||
|
public static final Block ORESPEEDPOWDER = registerBlock(ID.ORESPEEDPOWDER,
|
||||||
|
properties -> new BlockOre(properties.strength(2.0f), ID.SPEEDPOWDER));
|
||||||
|
public static final Block OREDEEPSLATESPEEDPOWDER = registerBlock(ID.OREDEEPSLATESPEEDPOWDER,
|
||||||
|
properties -> new BlockOre(properties.strength(2.1f), ID.SPEEDPOWDER));
|
||||||
|
public static final Block SALPETERBLOCK = registerBlock(ID.BLOCKSALPETER,
|
||||||
|
properties -> new BlockOre(properties.strength(1.5f), ID.SALPETER));
|
||||||
|
public static final Block SULFORBLOCK = registerBlock(ID.BLOCKSULFOR,
|
||||||
|
properties -> new BlockOre(properties.strength(1.5f), ID.SULFOR));
|
||||||
|
|
||||||
private static final Block registerBlock(String name, Properties properties) {
|
private static final Block registerBlock(Identifier identifier, Properties properties) {
|
||||||
return QuicklyBlocks.registerBlock(name, properties, p -> new Block(p));
|
return QuicklyBlocks.registerBlock(identifier, properties, p -> new Block(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Block registerBlock(String name, Function<Properties, Block> function) {
|
private static final Block registerBlock(Identifier identifier, Function<Properties, Block> function) {
|
||||||
return QuicklyBlocks.registerBlock(name, Properties.of(), function);
|
return QuicklyBlocks.registerBlock(identifier, Properties.of(), function);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Block registerBlock(String name, Properties properties, Function<Properties, Block> function) {
|
private static final Block registerBlock(Identifier identifier, Properties properties,
|
||||||
Identifier identifier = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, name);
|
Function<Properties, Block> function) {
|
||||||
Block block = function.apply(properties.setId(ResourceKey.create(Registries.BLOCK, identifier)));
|
Block block = function.apply(properties.setId(ResourceKey.create(Registries.BLOCK, identifier)));
|
||||||
Registry.register(BuiltInRegistries.BLOCK, identifier, block);
|
Registry.register(BuiltInRegistries.BLOCK, identifier, block);
|
||||||
BlockItem blockItem = new BlockItem(block, new Item.Properties()
|
BlockItem blockItem = new BlockItem(block, new Item.Properties()
|
||||||
@@ -50,13 +88,17 @@ public class QuicklyBlocks {
|
|||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the block from the identifier
|
||||||
|
*
|
||||||
|
* @param identifier the identifier
|
||||||
|
* @return the block or null
|
||||||
|
*/
|
||||||
|
public static final Block of(Identifier identifier) {
|
||||||
|
return BuiltInRegistries.BLOCK.getValue(identifier);
|
||||||
|
}
|
||||||
|
|
||||||
public static void registerModBlocks() {
|
public static void registerModBlocks() {
|
||||||
ItemGroupEvents.modifyEntriesEvent(CreativeModeTabs.BUILDING_BLOCKS).register(block -> {
|
Quickly.LOGGER.info("forbid the optimizer to ignore static block registration");
|
||||||
block.accept(KELPBUNDLE);
|
|
||||||
block.accept(TURQUOISEBLOCK);
|
|
||||||
block.accept(ORETURQUOISE);
|
|
||||||
block.accept(OREDEEPSLATETURQUOISE);
|
|
||||||
block.accept(COTTONPLANT);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,157 @@
|
|||||||
|
package de.jottyfan.minecraft.blockentity;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
|
||||||
|
import de.jottyfan.minecraft.block.BlockStacker;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.world.Container;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
import net.minecraft.world.item.Item;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.block.entity.BaseContainerBlockEntity;
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class BlockStackerEntity extends BlockEntity implements Container {
|
||||||
|
|
||||||
|
public static final Codec<Map<String, ItemStack>> ITEM_STACK_MAP_CODEC = Codec.unboundedMap(Codec.STRING,
|
||||||
|
ItemStack.CODEC);
|
||||||
|
|
||||||
|
private List<ItemStack> inventory = new ArrayList<>();
|
||||||
|
|
||||||
|
public BlockStackerEntity(BlockPos pos, BlockState blockState) {
|
||||||
|
super(QuicklyBlockEntity.BLOCKSTACKER_BLOCKENTITY, pos, blockState);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T extends BlockEntity> Object tick(Level level, BlockPos pos, BlockState state, T entity) {
|
||||||
|
pos.below();
|
||||||
|
BlockStacker block = (BlockStacker) state.getBlock();
|
||||||
|
BlockEntity source = level.getBlockEntity(pos.offset(block.getOffset(state, BlockStacker.SOURCE)));
|
||||||
|
BlockEntity dest = level.getBlockEntity(pos.offset(block.getOffset(state, BlockStacker.DEST)));
|
||||||
|
Boolean sourceIsLootable = source instanceof BaseContainerBlockEntity;
|
||||||
|
Boolean destIsLootable = dest instanceof BaseContainerBlockEntity;
|
||||||
|
if (sourceIsLootable && destIsLootable) {
|
||||||
|
BaseContainerBlockEntity lootableSource = (BaseContainerBlockEntity) source;
|
||||||
|
BaseContainerBlockEntity lootableDest = (BaseContainerBlockEntity) dest;
|
||||||
|
transferOneStack(lootableSource, lootableDest);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final Boolean transferOneStack(BaseContainerBlockEntity source, BaseContainerBlockEntity dest) {
|
||||||
|
Boolean result = false;
|
||||||
|
Integer sourceSlot = findItemStackPos(source, false);
|
||||||
|
if (sourceSlot != null) {
|
||||||
|
ItemStack sourceStack = source.getSlot(sourceSlot).get();
|
||||||
|
Integer destSlot = findItemStackPos(dest, sourceStack.getItem(), sourceStack.getCount());
|
||||||
|
if (destSlot != null) {
|
||||||
|
ItemStack destStack = dest.getSlot(destSlot).get();
|
||||||
|
Integer free = destStack.getItem().getDefaultMaxStackSize() - destStack.getCount();
|
||||||
|
Integer candidates = sourceStack.getCount();
|
||||||
|
Integer travellers = candidates > free ? free : candidates;
|
||||||
|
if (travellers > 0) {
|
||||||
|
dest.setItem(destSlot, new ItemStack(sourceStack.getItem(), destStack.getCount() + travellers));
|
||||||
|
source.removeItem(sourceSlot, travellers);
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Integer destFreeSlot = findItemStackPos(dest, true);
|
||||||
|
if (destFreeSlot != null) {
|
||||||
|
dest.setItem(destFreeSlot, new ItemStack(sourceStack.getItem(), sourceStack.getCount()));
|
||||||
|
source.removeItem(sourceSlot, sourceStack.getCount());
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Integer findItemStackPos(BaseContainerBlockEntity blockEntity, Item sourceItem, Integer sourceCount) {
|
||||||
|
Integer counter = 0;
|
||||||
|
while (counter < blockEntity.getContainerSize()) {
|
||||||
|
ItemStack stack = blockEntity.getItem(counter);
|
||||||
|
if (sourceItem.equals(stack.getItem())) {
|
||||||
|
Integer spaceLeft = stack.getItem().getDefaultMaxStackSize() - stack.getCount();
|
||||||
|
if (sourceCount <= spaceLeft || spaceLeft > 0) {
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Integer findItemStackPos(BaseContainerBlockEntity blockEntity, Boolean seekEmptyStack) {
|
||||||
|
Integer counter = 0;
|
||||||
|
while (counter < blockEntity.getContainerSize()) {
|
||||||
|
ItemStack stack = blockEntity.getItem(counter);
|
||||||
|
Boolean check = false;
|
||||||
|
if (seekEmptyStack) {
|
||||||
|
check = ItemStack.EMPTY.equals(stack) || stack.getCount() < 1;
|
||||||
|
} else {
|
||||||
|
check = !ItemStack.EMPTY.equals(stack) && stack.getCount() > 0;
|
||||||
|
}
|
||||||
|
if (check) {
|
||||||
|
return counter;
|
||||||
|
}
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearContent() {
|
||||||
|
inventory.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getContainerSize() {
|
||||||
|
return inventory.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack getItem(int slot) {
|
||||||
|
return inventory.get(slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack removeItem(int slot, int count) {
|
||||||
|
ItemStack stack = inventory.get(slot);
|
||||||
|
stack.shrink(count);
|
||||||
|
setChanged();
|
||||||
|
return stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack removeItemNoUpdate(int slot) {
|
||||||
|
ItemStack stack = inventory.get(slot);
|
||||||
|
stack.shrink(stack.getCount());
|
||||||
|
return stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setItem(int slot, ItemStack itemStack) {
|
||||||
|
inventory.set(slot, itemStack);
|
||||||
|
setChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean stillValid(Player player) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,141 @@
|
|||||||
|
package de.jottyfan.minecraft.blockentity;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import de.jottyfan.minecraft.block.BlockDrill;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.block.Blocks;
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class DrillBlockEntity extends BlockEntity {
|
||||||
|
|
||||||
|
private static final Integer MAXDRILLSTEP = 20;
|
||||||
|
|
||||||
|
private Integer drillstep;
|
||||||
|
private final Integer maxDrillStep;
|
||||||
|
|
||||||
|
public DrillBlockEntity(BlockPos pos, BlockState state) {
|
||||||
|
super(QuicklyBlockEntity.BLOCKENTITY_DRILL, pos, state);
|
||||||
|
this.maxDrillStep = MAXDRILLSTEP;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void tick(Level level, BlockPos pos, BlockState state, BlockEntity be) {
|
||||||
|
if (be instanceof DrillBlockEntity dbe) {
|
||||||
|
Direction dir = state.getValue(BlockDrill.FACING);
|
||||||
|
List<BlockPos> list = new ArrayList<>();
|
||||||
|
if (Direction.DOWN.equals(dir)) {
|
||||||
|
list = downFrom(pos);
|
||||||
|
} else if (Direction.EAST.equals(dir)) {
|
||||||
|
list = directedFrom(pos.east());
|
||||||
|
} else if (Direction.SOUTH.equals(dir)) {
|
||||||
|
list = directedFrom(pos.south());
|
||||||
|
} else if (Direction.WEST.equals(dir)) {
|
||||||
|
list = directedFrom(pos.west());
|
||||||
|
} else if (Direction.NORTH.equals(dir)) {
|
||||||
|
list = directedFrom(pos.north());
|
||||||
|
}
|
||||||
|
DrillBlockEntity.tick(level, pos, state, dbe, MAXDRILLSTEP, list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final List<BlockPos> directedFrom(BlockPos pos) {
|
||||||
|
List<BlockPos> list = new ArrayList<>();
|
||||||
|
list.add(pos);
|
||||||
|
list.add(pos.above());
|
||||||
|
list.add(pos.above(2));
|
||||||
|
list.add(pos.above(3));
|
||||||
|
list.add(pos.below()); // must be last position
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final List<BlockPos> downFrom(BlockPos pos) {
|
||||||
|
List<BlockPos> list = new ArrayList<>();
|
||||||
|
Integer tracesMod = pos.getY() % 8;
|
||||||
|
tracesMod = tracesMod < 0 ? tracesMod * -1 : tracesMod; // lower that 0 makes it negative
|
||||||
|
if (tracesMod != 0) {
|
||||||
|
list.add(pos.north());
|
||||||
|
}
|
||||||
|
if (tracesMod != 1) {
|
||||||
|
list.add(pos.north().west());
|
||||||
|
}
|
||||||
|
if (tracesMod != 2) {
|
||||||
|
list.add(pos.west());
|
||||||
|
}
|
||||||
|
if (tracesMod != 3) {
|
||||||
|
list.add(pos.south().west());
|
||||||
|
}
|
||||||
|
if (tracesMod != 4) {
|
||||||
|
list.add(pos.south());
|
||||||
|
}
|
||||||
|
if (tracesMod != 5) {
|
||||||
|
list.add(pos.south().east());
|
||||||
|
}
|
||||||
|
if (tracesMod != 6) {
|
||||||
|
list.add(pos.east());
|
||||||
|
}
|
||||||
|
if (tracesMod != 7) {
|
||||||
|
list.add(pos.north().east());
|
||||||
|
}
|
||||||
|
list.add(pos.below()); // must be last position
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static final void moveBlockWithEntity(BlockPos from, BlockPos to, Level level) {
|
||||||
|
BlockEntity be = level.getBlockEntity(from);
|
||||||
|
BlockState bs = level.getBlockState(from);
|
||||||
|
if (be != null) {
|
||||||
|
level.setBlockAndUpdate(from, Blocks.AIR.defaultBlockState());
|
||||||
|
Integer newFuel = bs.getValue(BlockDrill.FUEL) - 1;
|
||||||
|
level.setBlockAndUpdate(to, bs.setValue(BlockDrill.FUEL, newFuel));
|
||||||
|
level.removeBlockEntity(from);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static final Boolean drill(BlockPos pos, List<BlockPos> toList, Level level) {
|
||||||
|
Boolean lastSuccess = false;
|
||||||
|
for (BlockPos to : toList) {
|
||||||
|
if (!level.getBlockState(to).is(Blocks.BEDROCK)) {
|
||||||
|
level.destroyBlock(to, true);
|
||||||
|
lastSuccess = pos.below() != to; // no need for the falling one
|
||||||
|
} else {
|
||||||
|
lastSuccess = false; // in case that the last one is a bedrock
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lastSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void tick(Level level, BlockPos pos, BlockState state, DrillBlockEntity be, Integer maxDrillStep,
|
||||||
|
List<BlockPos> drillPosition) {
|
||||||
|
if (state.getValue(BlockDrill.FUEL) > 0) {
|
||||||
|
if (be.getDrillstep() < 1) {
|
||||||
|
be.setDrillstep(maxDrillStep);
|
||||||
|
if (drill(pos, drillPosition, level)) {
|
||||||
|
moveBlockWithEntity(pos, drillPosition.get(drillPosition.size() - 1), level);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
be.doDrillstep();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void doDrillstep() {
|
||||||
|
setDrillstep(getDrillstep() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getDrillstep() {
|
||||||
|
return drillstep == null ? maxDrillStep : drillstep;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDrillstep(Integer drillstep) {
|
||||||
|
this.drillstep = drillstep;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,183 @@
|
|||||||
|
package de.jottyfan.minecraft.blockentity;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
|
||||||
|
import de.jottyfan.minecraft.Quickly;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.world.Container;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import net.minecraft.world.entity.item.ItemEntity;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
import net.minecraft.world.level.block.entity.HopperBlockEntity;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.storage.ValueInput;
|
||||||
|
import net.minecraft.world.level.storage.ValueOutput;
|
||||||
|
import net.minecraft.world.phys.AABB;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ItemHoarderBlockEntity extends BlockEntity implements Container {
|
||||||
|
|
||||||
|
public static final Codec<Map<String, ItemStack>> ITEM_STACK_MAP_CODEC =
|
||||||
|
Codec.unboundedMap(Codec.STRING, ItemStack.CODEC);
|
||||||
|
|
||||||
|
private Map<String, ItemStack> stacks = new HashMap<>();
|
||||||
|
private static final Integer suckradius = 4;
|
||||||
|
|
||||||
|
public ItemHoarderBlockEntity(BlockPos pos, BlockState state) {
|
||||||
|
super(QuicklyBlockEntity.BLOCKENTITY_ITEMHOARDER, pos, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final static boolean setStackToSlots(ItemStack stack, Map<String, ItemStack> stacks) {
|
||||||
|
if (stack.isEmpty()) {
|
||||||
|
Quickly.LOGGER.info("FATAL!!! tried to set empty stack. Check your code!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
String key = stack.getItemName().getString();
|
||||||
|
ItemStack s = stacks.get(key);
|
||||||
|
if (s == null) {
|
||||||
|
stacks.put(key, stack);
|
||||||
|
} else {
|
||||||
|
stacks.get(key).grow(stack.getCount());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final void suck(Level level, BlockPos pos, ItemHoarderBlockEntity be) {
|
||||||
|
AABB checkArea = new AABB(pos).inflate(suckradius);
|
||||||
|
for (ItemEntity itemEntity : level.getEntitiesOfClass(ItemEntity.class, checkArea, Entity::isAlive)) {
|
||||||
|
ItemStack stack = itemEntity.getItem();
|
||||||
|
if (ItemHoarderBlockEntity.setStackToSlots(stack, be.getStacks())) {
|
||||||
|
itemEntity.discard();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final void dropToHopper(Level level, BlockPos pos, BlockState state,
|
||||||
|
ItemHoarderBlockEntity blockEntity) {
|
||||||
|
BlockEntity beBelow = level.getBlockEntity(pos.below());
|
||||||
|
if (beBelow instanceof Container targetInventory) {
|
||||||
|
for (String stackKey : blockEntity.getStacks().keySet()) {
|
||||||
|
ItemStack stackInSlot = blockEntity.getStack(stackKey);
|
||||||
|
if (!stackInSlot.isEmpty()) {
|
||||||
|
ItemStack toInsert = stackInSlot.copy();
|
||||||
|
int oldCount = toInsert.getCount();
|
||||||
|
ItemStack remainder = HopperBlockEntity.addItem(blockEntity, targetInventory, toInsert, Direction.UP);
|
||||||
|
int movedAmount = oldCount - remainder.getCount();
|
||||||
|
if (movedAmount > 0) {
|
||||||
|
stackInSlot.shrink(movedAmount);
|
||||||
|
blockEntity.setChanged();
|
||||||
|
targetInventory.setChanged();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ItemStack getStack(String stackKey) {
|
||||||
|
return stacks.get(stackKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void tick(Level level, BlockPos pos, BlockState state, ItemHoarderBlockEntity be) {
|
||||||
|
suck(level, pos, be);
|
||||||
|
dropToHopper(level, pos, state, be);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void saveAdditional(ValueOutput output) {
|
||||||
|
super.saveAdditional(output);
|
||||||
|
output.store("items", ITEM_STACK_MAP_CODEC, stacks);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void loadAdditional(ValueInput input) {
|
||||||
|
super.loadAdditional(input);
|
||||||
|
stacks.clear();
|
||||||
|
stacks.putAll(input.read("items", ITEM_STACK_MAP_CODEC).orElse(Map.of()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getSuckradius() {
|
||||||
|
return suckradius;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getContainerSize() {
|
||||||
|
return stacks.size() + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return stacks.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use getStack(String key) instead
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
public ItemStack getItem(int slot) {
|
||||||
|
// buggy; do not use this. The map wants to have an item name instead
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use getStack(String key).setCount(0) or such instead
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
public ItemStack removeItem(int slot, int count) {
|
||||||
|
// buggy; do not use this. The map wants to have an item name instead
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use getStack(String key).setCount(0) or such instead
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
public ItemStack removeItemNoUpdate(int slot) {
|
||||||
|
// buggy; do not use this. The map wants to have an item name instead
|
||||||
|
return ItemStack.EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param slot is ignored; the right slot is found by itemStack's name
|
||||||
|
* @param itemStack the itemStack to add
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setItem(int slot, ItemStack itemStack) {
|
||||||
|
ItemStack found = stacks.get(itemStack.getItemName().getString());
|
||||||
|
if (found != null) {
|
||||||
|
found.grow(itemStack.getCount());
|
||||||
|
} else if (!itemStack.isEmpty()) {
|
||||||
|
stacks.put(itemStack.getItemName().getString(), itemStack);
|
||||||
|
}
|
||||||
|
setChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean stillValid(Player player) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clearContent() {
|
||||||
|
stacks.clear();
|
||||||
|
setChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, ItemStack> getStacks() {
|
||||||
|
return stacks;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package de.jottyfan.minecraft.blockentity;
|
||||||
|
|
||||||
|
import de.jottyfan.minecraft.Quickly;
|
||||||
|
import de.jottyfan.minecraft.block.QuicklyBlocks;
|
||||||
|
import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityTypeBuilder;
|
||||||
|
import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityTypeBuilder.Factory;
|
||||||
|
import net.minecraft.core.Registry;
|
||||||
|
import net.minecraft.core.registries.BuiltInRegistries;
|
||||||
|
import net.minecraft.resources.Identifier;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class QuicklyBlockEntity<T extends BlockEntity> {
|
||||||
|
|
||||||
|
public static final BlockEntityType<ItemHoarderBlockEntity> BLOCKENTITY_ITEMHOARDER = new QuicklyBlockEntity<ItemHoarderBlockEntity>()
|
||||||
|
.registerBlockEntity("itemhoarderblockentity", ItemHoarderBlockEntity::new, QuicklyBlocks.ITEMHOARDER);
|
||||||
|
public static final BlockEntityType<DrillBlockEntity> BLOCKENTITY_DRILL = new QuicklyBlockEntity<DrillBlockEntity>()
|
||||||
|
.registerBlockEntity("drillblockentity", DrillBlockEntity::new, QuicklyBlocks.DRILL);
|
||||||
|
public static final BlockEntityType<BlockStackerEntity> BLOCKSTACKER_BLOCKENTITY = new QuicklyBlockEntity<BlockStackerEntity>()
|
||||||
|
.registerBlockEntity("blockstackerentity", BlockStackerEntity::new, QuicklyBlocks.STACKER);
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public BlockEntityType<T> registerBlockEntity(String name, Factory<? extends BlockEntity> factory, Block block) {
|
||||||
|
return (BlockEntityType<T>) Registry.register(
|
||||||
|
BuiltInRegistries.BLOCK_ENTITY_TYPE,
|
||||||
|
Identifier.fromNamespaceAndPath(Quickly.MOD_ID, name),
|
||||||
|
FabricBlockEntityTypeBuilder.create(factory, block).build()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final void registerBlockEntities() {
|
||||||
|
Quickly.LOGGER.info("forbid the optimizer to ignore static block entity registration"); }
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package de.jottyfan.minecraft.composter;
|
||||||
|
|
||||||
|
import de.jottyfan.minecraft.item.QuicklyItems;
|
||||||
|
import net.fabricmc.fabric.api.registry.CompostableRegistry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class QuicklyComposter {
|
||||||
|
|
||||||
|
public static final void registerComposterItems() {
|
||||||
|
CompostableRegistry.INSTANCE.add(QuicklyItems.COTTONSEED, 0.5f);
|
||||||
|
CompostableRegistry.INSTANCE.add(QuicklyItems.COTTON, 0.75f);
|
||||||
|
CompostableRegistry.INSTANCE.add(QuicklyItems.CANOLASEED, 0.5f);
|
||||||
|
CompostableRegistry.INSTANCE.add(QuicklyItems.CANOLA, 0.75f);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
207
src/main/java/de/jottyfan/minecraft/event/EventBlockBreak.java
Normal file
207
src/main/java/de/jottyfan/minecraft/event/EventBlockBreak.java
Normal file
@@ -0,0 +1,207 @@
|
|||||||
|
package de.jottyfan.minecraft.event;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import de.jottyfan.minecraft.item.HarvestRange;
|
||||||
|
import de.jottyfan.minecraft.item.QuicklyItems;
|
||||||
|
import de.jottyfan.minecraft.item.ToolRangeable;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.world.entity.ExperienceOrb;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
import net.minecraft.world.item.Item;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.Blocks;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class EventBlockBreak {
|
||||||
|
private enum BlockBreakDirection {
|
||||||
|
UPWARDS, ALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* break surrounding block if item is of ToolRangeable
|
||||||
|
*
|
||||||
|
* @param level
|
||||||
|
* @param blockPos
|
||||||
|
* @param blockState
|
||||||
|
* @param player
|
||||||
|
* @param oldBlock
|
||||||
|
* @return true if this range breaking routine has been used, false otherwise
|
||||||
|
*/
|
||||||
|
public boolean doBreakBlock(Level level, BlockPos blockPos, BlockState blockState, Player player, Block oldBlock) {
|
||||||
|
ItemStack mainHandItemStack = player.getMainHandItem();
|
||||||
|
if (mainHandItemStack != null) {
|
||||||
|
Item item = mainHandItemStack.getItem();
|
||||||
|
if (item instanceof ToolRangeable) {
|
||||||
|
ToolRangeable tool = (ToolRangeable) item;
|
||||||
|
// not needed when added to before block break
|
||||||
|
// if (!world.getBlockState(blockPos).getBlock().equals(oldBlock)) {
|
||||||
|
// // recreate old block to make it breakable; otherwise, the recursive algorithm stops directly
|
||||||
|
// // this leads to the BUG that blocks with no neighbour will respawn and drop -> unlimited items.
|
||||||
|
// world.setBlockState(blockPos, oldBlock.getDefaultState());
|
||||||
|
// }
|
||||||
|
int handled = handleRangeableTools(tool, mainHandItemStack, level, oldBlock, blockPos, player);
|
||||||
|
if (handled >= 255) {
|
||||||
|
// reward for using rangeable tool very successful
|
||||||
|
level.addFreshEntity(
|
||||||
|
new ExperienceOrb(level, blockPos.getX(), blockPos.getY(), blockPos.getZ(), handled / 255));
|
||||||
|
}
|
||||||
|
return handled > 0; // this way, a rangeable pickaxe can break a dirt block
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* handle the rangeable tools break event
|
||||||
|
*
|
||||||
|
* @param tool the tool that has been used
|
||||||
|
* @param itemStack the item stack
|
||||||
|
* @param level the world
|
||||||
|
* @param block the block to break
|
||||||
|
* @param pos the position of the current block
|
||||||
|
* @param player the current player
|
||||||
|
* @return number of affected blocks
|
||||||
|
*/
|
||||||
|
private int handleRangeableTools(ToolRangeable tool, ItemStack itemStack, Level level, Block currentBlock,
|
||||||
|
BlockPos pos, Player player) {
|
||||||
|
List<Block> validBlocks = tool.getBlockList(currentBlock);
|
||||||
|
HarvestRange range = tool.getRange(itemStack);
|
||||||
|
List<String> visitedBlocks = new ArrayList<>();
|
||||||
|
if (QuicklyItems.SPEEDAXE == tool) {
|
||||||
|
return breakBlockRecursive(visitedBlocks, level, validBlocks, pos, tool, range, BlockBreakDirection.UPWARDS,
|
||||||
|
player, true);
|
||||||
|
} else if (QuicklyItems.SPEEDPICKAXE == tool) {
|
||||||
|
return breakBlockRecursive(visitedBlocks, level, validBlocks, pos, tool, range, BlockBreakDirection.ALL, player,
|
||||||
|
false);
|
||||||
|
} else if (QuicklyItems.SPEEDSHOVEL == tool) {
|
||||||
|
return breakBlockRecursive(visitedBlocks, level, validBlocks, pos, tool, range, BlockBreakDirection.ALL, player,
|
||||||
|
false);
|
||||||
|
} else if (QuicklyItems.SPEEDHOE == tool) {
|
||||||
|
return breakBlockRecursive(visitedBlocks, level, validBlocks, pos, tool, range, BlockBreakDirection.ALL, player,
|
||||||
|
false);
|
||||||
|
} else if (QuicklyItems.QUICKIEAXE == tool) {
|
||||||
|
return breakBlockRecursive(visitedBlocks, level, validBlocks, pos, tool, range, BlockBreakDirection.UPWARDS,
|
||||||
|
player, true);
|
||||||
|
} else if (QuicklyItems.QUICKIEPICKAXE == tool) {
|
||||||
|
return breakBlockRecursive(visitedBlocks, level, validBlocks, pos, tool, range, BlockBreakDirection.ALL, player,
|
||||||
|
false);
|
||||||
|
} else if (QuicklyItems.QUICKIESHOVEL == tool) {
|
||||||
|
return breakBlockRecursive(visitedBlocks, level, validBlocks, pos, tool, range, BlockBreakDirection.ALL, player,
|
||||||
|
false);
|
||||||
|
} else if (QuicklyItems.QUICKIEHOE == tool) {
|
||||||
|
return breakBlockRecursive(visitedBlocks, level, validBlocks, pos, tool, range, BlockBreakDirection.ALL, player,
|
||||||
|
false);
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* break block recursively;
|
||||||
|
*
|
||||||
|
* @param visitedBlocks the positions of visited blocks
|
||||||
|
* @param level the world
|
||||||
|
* @param validBlocks the blocks to break
|
||||||
|
* @param tool the tool used
|
||||||
|
* @param range the range left over
|
||||||
|
* @param pos the position
|
||||||
|
* @param blockBreakDirection the direction for the recursive call
|
||||||
|
* @param player the player
|
||||||
|
* @return number of affected blocks
|
||||||
|
*/
|
||||||
|
private int breakBlockRecursive(List<String> visitedBlocks, Level level, List<Block> validBlocks, BlockPos pos,
|
||||||
|
ToolRangeable tool, HarvestRange range, BlockBreakDirection blockBreakDirection, Player player,
|
||||||
|
boolean breakLeaves) {
|
||||||
|
// boolean ignoreSpawn = visitedBlocks.size() < 1; // with this, the already broken block can be omitted to spawn
|
||||||
|
if (visitedBlocks.contains(pos.toString())) {
|
||||||
|
return 0;
|
||||||
|
} else if (validBlocks == null) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
visitedBlocks.add(pos.toString());
|
||||||
|
}
|
||||||
|
Integer affected = 0;
|
||||||
|
BlockState blockState = level.getBlockState(pos);
|
||||||
|
if (tool.canBreakNeighbors(blockState)) {
|
||||||
|
Block currentBlock = blockState.getBlock();
|
||||||
|
if (validBlocks.contains(currentBlock)) {
|
||||||
|
// if (!ignoreSpawn) {
|
||||||
|
Block.dropResources(blockState, level, pos); // includes xorbs
|
||||||
|
// }
|
||||||
|
affected += 1;
|
||||||
|
level.setBlockAndUpdate(pos, Blocks.AIR.defaultBlockState());
|
||||||
|
if (range == null || range.getxRange() > 1 || range.getyRange() > 1 || range.getzRange() > 1) {
|
||||||
|
HarvestRange nextRadius = range == null ? null : range.addXYZ(-1);
|
||||||
|
affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.north(), tool, nextRadius,
|
||||||
|
blockBreakDirection, player, breakLeaves);
|
||||||
|
affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.north().east(), tool, nextRadius,
|
||||||
|
blockBreakDirection, player, breakLeaves);
|
||||||
|
affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.north().west(), tool, nextRadius,
|
||||||
|
blockBreakDirection, player, breakLeaves);
|
||||||
|
affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.south(), tool, nextRadius,
|
||||||
|
blockBreakDirection, player, breakLeaves);
|
||||||
|
affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.south().east(), tool, nextRadius,
|
||||||
|
blockBreakDirection, player, breakLeaves);
|
||||||
|
affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.south().west(), tool, nextRadius,
|
||||||
|
blockBreakDirection, player, breakLeaves);
|
||||||
|
affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.east(), tool, nextRadius,
|
||||||
|
blockBreakDirection, player, breakLeaves);
|
||||||
|
affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.west(), tool, nextRadius,
|
||||||
|
blockBreakDirection, player, breakLeaves);
|
||||||
|
affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.above(), tool, nextRadius,
|
||||||
|
blockBreakDirection, player, breakLeaves);
|
||||||
|
affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.above().north(), tool, nextRadius,
|
||||||
|
blockBreakDirection, player, breakLeaves);
|
||||||
|
affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.above().north().east(), tool,
|
||||||
|
nextRadius, blockBreakDirection, player, breakLeaves);
|
||||||
|
affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.above().north().west(), tool,
|
||||||
|
nextRadius, blockBreakDirection, player, breakLeaves);
|
||||||
|
affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.above().east(), tool, nextRadius,
|
||||||
|
blockBreakDirection, player, breakLeaves);
|
||||||
|
affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.above().west(), tool, nextRadius,
|
||||||
|
blockBreakDirection, player, breakLeaves);
|
||||||
|
affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.above().south().east(), tool,
|
||||||
|
nextRadius, blockBreakDirection, player, breakLeaves);
|
||||||
|
affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.above().south().west(), tool,
|
||||||
|
nextRadius, blockBreakDirection, player, breakLeaves);
|
||||||
|
affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.above().south(), tool, nextRadius,
|
||||||
|
blockBreakDirection, player, breakLeaves);
|
||||||
|
|
||||||
|
if (BlockBreakDirection.ALL.equals(blockBreakDirection)) {
|
||||||
|
affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.below(), tool, nextRadius,
|
||||||
|
blockBreakDirection, player, breakLeaves);
|
||||||
|
affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.below().north(), tool, nextRadius,
|
||||||
|
blockBreakDirection, player, breakLeaves);
|
||||||
|
affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.below().south(), tool, nextRadius,
|
||||||
|
blockBreakDirection, player, breakLeaves);
|
||||||
|
affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.below().east(), tool, nextRadius,
|
||||||
|
blockBreakDirection, player, breakLeaves);
|
||||||
|
affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.below().west(), tool, nextRadius,
|
||||||
|
blockBreakDirection, player, breakLeaves);
|
||||||
|
affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.below().north().east(), tool,
|
||||||
|
nextRadius, blockBreakDirection, player, breakLeaves);
|
||||||
|
affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.below().north().west(), tool,
|
||||||
|
nextRadius, blockBreakDirection, player, breakLeaves);
|
||||||
|
affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.below().south().east(), tool,
|
||||||
|
nextRadius, blockBreakDirection, player, breakLeaves);
|
||||||
|
affected += breakBlockRecursive(visitedBlocks, level, validBlocks, pos.below().south().west(), tool,
|
||||||
|
nextRadius, blockBreakDirection, player, breakLeaves);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return affected;
|
||||||
|
}
|
||||||
|
}
|
||||||
24
src/main/java/de/jottyfan/minecraft/event/QuicklyEvents.java
Normal file
24
src/main/java/de/jottyfan/minecraft/event/QuicklyEvents.java
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package de.jottyfan.minecraft.event;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.event.player.PlayerBlockBreakEvents;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class QuicklyEvents {
|
||||||
|
public static final void registerBlockBreak() {
|
||||||
|
PlayerBlockBreakEvents.BEFORE.register((world, player, pos, state, blockEntity) -> {
|
||||||
|
if (!world.isClientSide()) {
|
||||||
|
if (new EventBlockBreak().doBreakBlock(world, pos, state, player, state.getBlock())) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,7 +17,24 @@ import net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
|||||||
*/
|
*/
|
||||||
public class QuicklyFeatures {
|
public class QuicklyFeatures {
|
||||||
public static final ResourceKey<ConfiguredFeature<?, ?>> CF_ORETURQUOISE = genCf("oreturquoise");
|
public static final ResourceKey<ConfiguredFeature<?, ?>> CF_ORETURQUOISE = genCf("oreturquoise");
|
||||||
|
public static final ResourceKey<ConfiguredFeature<?, ?>> CF_ORESULFOR = genCf("oresulfor");
|
||||||
|
public static final ResourceKey<ConfiguredFeature<?, ?>> CF_OREDEEPSLATESULFUR = genCf("oredepslatesulfor");
|
||||||
|
public static final ResourceKey<ConfiguredFeature<?, ?>> CF_ORESALPETER = genCf("oresalpeter");
|
||||||
|
public static final ResourceKey<ConfiguredFeature<?, ?>> CF_ORENETHERSULFOR = genCf("orenethersulfor");
|
||||||
|
public static final ResourceKey<ConfiguredFeature<?, ?>> CF_DIRTSALPETER = genCf("dirtsalpeter");
|
||||||
|
public static final ResourceKey<ConfiguredFeature<?, ?>> CF_SANDSALPETER = genCf("sandsalpeter");
|
||||||
|
public static final ResourceKey<ConfiguredFeature<?, ?>> CF_ORESANDSALPETER = genCf("oresandsalpeter");
|
||||||
|
public static final ResourceKey<ConfiguredFeature<?, ?>> CF_ORESPEEDPOWDER = genCf("orespeedpowder");
|
||||||
|
|
||||||
public static final ResourceKey<PlacedFeature> PF_ORETURQUOISE = genPf("oreturquoise");
|
public static final ResourceKey<PlacedFeature> PF_ORETURQUOISE = genPf("oreturquoise");
|
||||||
|
public static final ResourceKey<PlacedFeature> PF_ORESULFOR = genPf("oresulfor");
|
||||||
|
public static final ResourceKey<PlacedFeature> PF_OREDEEPSLATESULFOR = genPf("oredeepslatesulfor");
|
||||||
|
public static final ResourceKey<PlacedFeature> PF_ORESALPETER = genPf("oresalpeter");
|
||||||
|
public static final ResourceKey<PlacedFeature> PF_ORENETHERSULFOR = genPf("orenethersulfor");
|
||||||
|
public static final ResourceKey<PlacedFeature> PF_DIRTSALPETER = genPf("dirtsalpeter");
|
||||||
|
public static final ResourceKey<PlacedFeature> PF_SANDSALPETER = genPf("sandsalpeter");
|
||||||
|
public static final ResourceKey<PlacedFeature> PF_ORESANDSALPETER = genPf("oresandsalpeter");
|
||||||
|
public static final ResourceKey<PlacedFeature> PF_ORESPEEDPOWDER = genPf("orespeedpowder");
|
||||||
|
|
||||||
private static final ResourceKey<ConfiguredFeature<?, ?>> genCf(String name) {
|
private static final ResourceKey<ConfiguredFeature<?, ?>> genCf(String name) {
|
||||||
return ResourceKey.create(Registries.CONFIGURED_FEATURE, Identifier.fromNamespaceAndPath(Quickly.MOD_ID, name));
|
return ResourceKey.create(Registries.CONFIGURED_FEATURE, Identifier.fromNamespaceAndPath(Quickly.MOD_ID, name));
|
||||||
@@ -29,5 +46,14 @@ public class QuicklyFeatures {
|
|||||||
|
|
||||||
public static final void registerFeatures() {
|
public static final void registerFeatures() {
|
||||||
BiomeModifications.addFeature(BiomeSelectors.foundInOverworld(), GenerationStep.Decoration.UNDERGROUND_ORES, PF_ORETURQUOISE);
|
BiomeModifications.addFeature(BiomeSelectors.foundInOverworld(), GenerationStep.Decoration.UNDERGROUND_ORES, PF_ORETURQUOISE);
|
||||||
|
BiomeModifications.addFeature(BiomeSelectors.foundInOverworld(), GenerationStep.Decoration.UNDERGROUND_ORES, PF_ORESULFOR);
|
||||||
|
BiomeModifications.addFeature(BiomeSelectors.foundInOverworld(), GenerationStep.Decoration.UNDERGROUND_ORES, PF_ORESALPETER);
|
||||||
|
BiomeModifications.addFeature(BiomeSelectors.foundInOverworld(), GenerationStep.Decoration.UNDERGROUND_ORES, PF_DIRTSALPETER);
|
||||||
|
BiomeModifications.addFeature(BiomeSelectors.foundInOverworld(), GenerationStep.Decoration.UNDERGROUND_ORES, PF_SANDSALPETER);
|
||||||
|
BiomeModifications.addFeature(BiomeSelectors.foundInOverworld(), GenerationStep.Decoration.UNDERGROUND_ORES, PF_ORESANDSALPETER);
|
||||||
|
BiomeModifications.addFeature(BiomeSelectors.foundInOverworld(), GenerationStep.Decoration.UNDERGROUND_ORES, PF_OREDEEPSLATESULFOR);
|
||||||
|
BiomeModifications.addFeature(BiomeSelectors.foundInOverworld(), GenerationStep.Decoration.UNDERGROUND_ORES, PF_ORESPEEDPOWDER);
|
||||||
|
|
||||||
|
BiomeModifications.addFeature(BiomeSelectors.foundInTheNether(), GenerationStep.Decoration.UNDERGROUND_ORES, PF_ORENETHERSULFOR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
136
src/main/java/de/jottyfan/minecraft/item/HarvestRange.java
Normal file
136
src/main/java/de/jottyfan/minecraft/item/HarvestRange.java
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
package de.jottyfan.minecraft.item;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class HarvestRange implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
private int xRange;
|
||||||
|
private int yRange;
|
||||||
|
private int zRange;
|
||||||
|
|
||||||
|
public HarvestRange(int xyzRange) {
|
||||||
|
super();
|
||||||
|
this.xRange = xyzRange;
|
||||||
|
this.yRange = xyzRange;
|
||||||
|
this.zRange = xyzRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HarvestRange(int[] xyzRange) {
|
||||||
|
super();
|
||||||
|
this.xRange = xyzRange[0];
|
||||||
|
this.yRange = xyzRange[1];
|
||||||
|
this.zRange = xyzRange[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
public HarvestRange(int xRange, int yRange, int zRange) {
|
||||||
|
super();
|
||||||
|
this.xRange = xRange;
|
||||||
|
this.yRange = yRange;
|
||||||
|
this.zRange = zRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
buf.append(xRange).append(":");
|
||||||
|
buf.append(yRange).append(":");
|
||||||
|
buf.append(zRange).append(":");
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* add i to x, y and z and return the resulting class as a new one
|
||||||
|
*
|
||||||
|
* @param i the summand
|
||||||
|
* @return the new class
|
||||||
|
*/
|
||||||
|
public HarvestRange addXYZ(int i) {
|
||||||
|
return new HarvestRange(xRange + i, yRange + i, zRange + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get range as int array
|
||||||
|
*
|
||||||
|
* @return the int array
|
||||||
|
*/
|
||||||
|
public int[] getRangeAsArray() {
|
||||||
|
return new int[] { xRange, yRange, zRange };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get range as blockpos array; find all the block positions for the distance of
|
||||||
|
* xRange, yRange and zRange
|
||||||
|
*
|
||||||
|
* @param pos the reference position
|
||||||
|
* @param ignoreY if true, ignore the height
|
||||||
|
* @param reduce values to reduce range
|
||||||
|
* @return the list of block positions; an empty list at least
|
||||||
|
*/
|
||||||
|
public List<BlockPos> getRangeAsBlockPosArray(BlockPos pos, boolean ignoreY, BlockPos reduce) {
|
||||||
|
List<BlockPos> blockPositions = new ArrayList<>();
|
||||||
|
int xBorder = xRange - reduce.getX();
|
||||||
|
int yBorder = ignoreY ? 0 : yRange - reduce.getY();
|
||||||
|
int zBorder = zRange - reduce.getZ();
|
||||||
|
for (int x = -xBorder; x <= xBorder; x++) {
|
||||||
|
for (int z = -zBorder; z <= zBorder; z++) {
|
||||||
|
for (int y = -yBorder; y <= yBorder; y++) {
|
||||||
|
if (ignoreY || Math.abs(x) + Math.abs(y) + Math.abs(z) <= Math.max(Math.max(xBorder, yBorder), zBorder)) {
|
||||||
|
blockPositions.add(pos.offset(x, y, z));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return blockPositions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the xRange
|
||||||
|
*/
|
||||||
|
public int getxRange() {
|
||||||
|
return xRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param xRange the xRange to set
|
||||||
|
*/
|
||||||
|
public void setxRange(int xRange) {
|
||||||
|
this.xRange = xRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the yRange
|
||||||
|
*/
|
||||||
|
public int getyRange() {
|
||||||
|
return yRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param yRange the yRange to set
|
||||||
|
*/
|
||||||
|
public void setyRange(int yRange) {
|
||||||
|
this.yRange = yRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the zRange
|
||||||
|
*/
|
||||||
|
public int getzRange() {
|
||||||
|
return zRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param zRange the zRange to set
|
||||||
|
*/
|
||||||
|
public void setzRange(int zRange) {
|
||||||
|
this.zRange = zRange;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package de.jottyfan.minecraft.item;
|
||||||
|
|
||||||
|
import java.util.EnumMap;
|
||||||
|
|
||||||
|
import de.jottyfan.minecraft.Quickly;
|
||||||
|
import net.minecraft.core.Registry;
|
||||||
|
import net.minecraft.resources.Identifier;
|
||||||
|
import net.minecraft.resources.ResourceKey;
|
||||||
|
import net.minecraft.sounds.SoundEvents;
|
||||||
|
import net.minecraft.util.Util;
|
||||||
|
import net.minecraft.world.item.equipment.ArmorMaterial;
|
||||||
|
import net.minecraft.world.item.equipment.ArmorType;
|
||||||
|
import net.minecraft.world.item.equipment.EquipmentAsset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ModArmorMaterials {
|
||||||
|
static ResourceKey<? extends Registry<EquipmentAsset>> REGISTRY_KEY = ResourceKey.createRegistryKey(Identifier.fromNamespaceAndPath("minecraft", "equipment_asset"));
|
||||||
|
public static final ResourceKey<EquipmentAsset> TURQUOISE_KEY = ResourceKey.create(REGISTRY_KEY, Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "turquoise"));
|
||||||
|
|
||||||
|
public static final ArmorMaterial TURQUOISE_ARMOR_MATERIAL = new ArmorMaterial(500, Util.make(new EnumMap<>(ArmorType.class), map -> {
|
||||||
|
map.put(ArmorType.BOOTS, 4);
|
||||||
|
map.put(ArmorType.LEGGINGS, 8);
|
||||||
|
map.put(ArmorType.CHESTPLATE, 15);
|
||||||
|
map.put(ArmorType.HELMET, 4);
|
||||||
|
map.put(ArmorType.BODY, 8);
|
||||||
|
}), 20, SoundEvents.ARMOR_EQUIP_DIAMOND, 0, 0, null, TURQUOISE_KEY);
|
||||||
|
}
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
package de.jottyfan.minecraft.item;
|
package de.jottyfan.minecraft.item;
|
||||||
|
|
||||||
import de.jottyfan.minecraft.Quickly;
|
import de.jottyfan.minecraft.block.QuicklyBlocks;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.registries.BuiltInRegistries;
|
|
||||||
import net.minecraft.resources.Identifier;
|
import net.minecraft.resources.Identifier;
|
||||||
import net.minecraft.world.InteractionResult;
|
import net.minecraft.world.InteractionResult;
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
@@ -18,15 +17,15 @@ import net.minecraft.world.level.block.state.BlockState;
|
|||||||
*/
|
*/
|
||||||
public class Plant extends Item {
|
public class Plant extends Item {
|
||||||
|
|
||||||
private String plantName;
|
private Identifier plantId;
|
||||||
|
|
||||||
public Plant(Properties properties, String plantName) {
|
public Plant(QIP properties) {
|
||||||
super(properties);
|
super(properties);
|
||||||
this.plantName = plantName;
|
this.plantId = properties.getBlockId();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Block getPlant() {
|
private Block getPlant() {
|
||||||
return BuiltInRegistries.BLOCK.getValue(Identifier.fromNamespaceAndPath(Quickly.MOD_ID, plantName));
|
return QuicklyBlocks.of(plantId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
66
src/main/java/de/jottyfan/minecraft/item/QAxe.java
Normal file
66
src/main/java/de/jottyfan/minecraft/item/QAxe.java
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
package de.jottyfan.minecraft.item;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
import net.minecraft.tags.BlockTags;
|
||||||
|
import net.minecraft.tags.ItemTags;
|
||||||
|
import net.minecraft.world.item.AxeItem;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.ToolMaterial;
|
||||||
|
import net.minecraft.world.level.ItemLike;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.LeavesBlock;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class QAxe extends AxeItem implements ToolRangeable {
|
||||||
|
|
||||||
|
private final HarvestRange range;
|
||||||
|
|
||||||
|
public QAxe(QIP properties) {
|
||||||
|
super(new ToolMaterial(BlockTags.INCORRECT_FOR_DIAMOND_TOOL, properties.getDurability(), 7f, 1f, 15, ItemTags.DIAMOND_TOOL_MATERIALS), 7f, 3.1f, properties);
|
||||||
|
this.range = properties.getHarvestRange();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HarvestRange getRange(ItemStack stack) {
|
||||||
|
return range;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check if the block is a leaves block
|
||||||
|
*
|
||||||
|
* @param blockIn the block
|
||||||
|
* @return true or false
|
||||||
|
*/
|
||||||
|
private boolean isLeavesBlock(BlockState blockIn) {
|
||||||
|
boolean vanillaLeaves = blockIn.getBlock() instanceof LeavesBlock;
|
||||||
|
boolean terrestriaLeaves = false;
|
||||||
|
try {
|
||||||
|
Class<?> extendedLeavesBlock = Class.forName("com.terraformersmc.terraform.leaves.block.ExtendedLeavesBlock");
|
||||||
|
terrestriaLeaves = extendedLeavesBlock.isInstance(blockIn.getBlock());
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
// no terrestria mod available, so ignore this
|
||||||
|
// using this approach instead of the instanceof functionality, we don't need to refer to terrestria
|
||||||
|
// and omit a crash on installations that do not have or want terrestria available
|
||||||
|
}
|
||||||
|
boolean blockTagLeaves = blockIn.is(BlockTags.LEAVES);
|
||||||
|
return vanillaLeaves || terrestriaLeaves || blockTagLeaves;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canBreakNeighbors(BlockState blockIn) {
|
||||||
|
return new ItemStack((ItemLike) this).isCorrectToolForDrops(blockIn) || isLeavesBlock(blockIn) || blockIn.is(BlockTags.LOGS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Block> getBlockList(Block block) {
|
||||||
|
return Lists.newArrayList(block);
|
||||||
|
}
|
||||||
|
}
|
||||||
98
src/main/java/de/jottyfan/minecraft/item/QHoe.java
Normal file
98
src/main/java/de/jottyfan/minecraft/item/QHoe.java
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
package de.jottyfan.minecraft.item;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.tags.BlockTags;
|
||||||
|
import net.minecraft.tags.ItemTags;
|
||||||
|
import net.minecraft.world.InteractionResult;
|
||||||
|
import net.minecraft.world.item.HoeItem;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.ToolMaterial;
|
||||||
|
import net.minecraft.world.item.context.UseOnContext;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.Blocks;
|
||||||
|
import net.minecraft.world.level.block.CropBlock;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.phys.BlockHitResult;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class QHoe extends HoeItem implements ToolRangeable {
|
||||||
|
|
||||||
|
public QIP properties;
|
||||||
|
|
||||||
|
public QHoe(QIP properties) {
|
||||||
|
super(new ToolMaterial(BlockTags.INCORRECT_FOR_DIAMOND_TOOL, properties.getDurability(), 7f, 1f, 15, ItemTags.DIAMOND_TOOL_MATERIALS), 7f, 3.1f, properties);
|
||||||
|
this.properties = properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InteractionResult useOn(UseOnContext context) {
|
||||||
|
InteractionResult res = super.useOn(context);
|
||||||
|
boolean isCrop = context.getLevel().getBlockState(context.getClickedPos()).getBlock() instanceof CropBlock;
|
||||||
|
if (!InteractionResult.PASS.equals(res) || isCrop) {
|
||||||
|
HarvestRange range = properties.getHarvestRange();
|
||||||
|
for (int x = -range.getxRange(); x <= range.getxRange(); x++) {
|
||||||
|
for (int y = -range.getyRange(); y <= range.getyRange(); y++) {
|
||||||
|
for (int z = -range.getzRange(); z <= range.getzRange(); z++) {
|
||||||
|
if (!isCrop) {
|
||||||
|
removePossibleGrass(context.getLevel(), new BlockPos(x, y, z));
|
||||||
|
BlockHitResult bhr = new BlockHitResult(context.getClickedPos().getCenter(), Direction.UP,
|
||||||
|
context.getClickedPos().offset(x, y, z), false);
|
||||||
|
UseOnContext ctx = new UseOnContext(context.getPlayer(), context.getHand(), bhr);
|
||||||
|
super.useOn(ctx);
|
||||||
|
} else {
|
||||||
|
harvestIfPossible(context.getClickedPos().offset(x, y, z), context.getLevel());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removePossibleGrass(Level level, BlockPos pos) {
|
||||||
|
Block block = level.getBlockState(pos).getBlock();
|
||||||
|
Boolean grassFound = Blocks.FERN.equals(block) || Blocks.LARGE_FERN.equals(block)
|
||||||
|
|| Blocks.SHORT_GRASS.equals(block) || Blocks.TALL_GRASS.equals(block);
|
||||||
|
if (grassFound) {
|
||||||
|
level.destroyBlock(pos, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void harvestIfPossible(BlockPos pos, Level level) {
|
||||||
|
BlockState blockState = level.getBlockState(pos);
|
||||||
|
Block block = blockState.getBlock();
|
||||||
|
if (block instanceof CropBlock) {
|
||||||
|
CropBlock cBlock = (CropBlock) block;
|
||||||
|
if (cBlock.isMaxAge(blockState)) {
|
||||||
|
Block.dropResources(blockState, level, pos);
|
||||||
|
level.setBlockAndUpdate(pos, cBlock.defaultBlockState());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canBreakNeighbors(BlockState blockState) {
|
||||||
|
return new ItemStack(this).isCorrectToolForDrops(blockState) || Blocks.TALL_GRASS.equals(blockState.getBlock())
|
||||||
|
|| Blocks.FERN.equals(blockState.getBlock()) || Blocks.LARGE_FERN.equals(blockState.getBlock());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Block> getBlockList(Block block) {
|
||||||
|
return Lists.newArrayList(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HarvestRange getRange(ItemStack stack) {
|
||||||
|
return properties.getHarvestRange();
|
||||||
|
}
|
||||||
|
}
|
||||||
137
src/main/java/de/jottyfan/minecraft/item/QIP.java
Normal file
137
src/main/java/de/jottyfan/minecraft/item/QIP.java
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
package de.jottyfan.minecraft.item;
|
||||||
|
|
||||||
|
import net.minecraft.resources.Identifier;
|
||||||
|
import net.minecraft.resources.ResourceKey;
|
||||||
|
import net.minecraft.world.item.Item;
|
||||||
|
import net.minecraft.world.item.equipment.ArmorMaterial;
|
||||||
|
import net.minecraft.world.item.equipment.ArmorType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class QIP extends Item.Properties {
|
||||||
|
private Item fallbackItem;
|
||||||
|
private HarvestRange harvestRange;
|
||||||
|
private Integer durability;
|
||||||
|
private Integer minDrops;
|
||||||
|
private Identifier blockId;
|
||||||
|
|
||||||
|
public static final QIP of(Integer xRange, Integer yRange, Integer zRange, Integer durability) {
|
||||||
|
QIP properties = new QIP();
|
||||||
|
properties.setHarvestRange(new HarvestRange(xRange, yRange, zRange));
|
||||||
|
properties.setDurability(durability);
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final QIP of(Item fallbackItem, Integer harvestRange, Integer durability) {
|
||||||
|
QIP properties = new QIP();
|
||||||
|
properties.setFallbackItem(fallbackItem);
|
||||||
|
properties.setHarvestRange(new HarvestRange(harvestRange));
|
||||||
|
properties.setDurability(durability);
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final QIP of(Integer harvestRange, Integer durability) {
|
||||||
|
QIP properties = new QIP();
|
||||||
|
properties.setHarvestRange(new HarvestRange(harvestRange));
|
||||||
|
properties.setDurability(durability);
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static QIP of(Integer minDrops) {
|
||||||
|
QIP properties = new QIP();
|
||||||
|
properties.setMinDrops(minDrops);
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static QIP of(Identifier blockId) {
|
||||||
|
QIP properties = new QIP();
|
||||||
|
properties.setBlockId(blockId);
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public QIP humanoidArmor(ArmorMaterial material, ArmorType type) {
|
||||||
|
super.humanoidArmor(material, type);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public QIP stacksTo(int max) {
|
||||||
|
super.stacksTo(max);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final QIP setVanilla(ResourceKey<Item> id, Identifier modelId) {
|
||||||
|
super.setId(id);
|
||||||
|
super.modelId(modelId);
|
||||||
|
super.useItemDescriptionPrefix();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setFallbackItem(Item fallbackItem) {
|
||||||
|
this.fallbackItem = fallbackItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Item getFallbackItem() {
|
||||||
|
return fallbackItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the harvestRange
|
||||||
|
*/
|
||||||
|
public HarvestRange getHarvestRange() {
|
||||||
|
return harvestRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param harvestRange the harvestRange to set
|
||||||
|
*/
|
||||||
|
public void setHarvestRange(HarvestRange harvestRange) {
|
||||||
|
this.harvestRange = harvestRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the durability
|
||||||
|
*/
|
||||||
|
public Integer getDurability() {
|
||||||
|
return durability;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param durability the durability to set
|
||||||
|
*/
|
||||||
|
public void setDurability(Integer durability) {
|
||||||
|
this.durability = durability;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the minDrops
|
||||||
|
*/
|
||||||
|
public Integer getMinDrops() {
|
||||||
|
return minDrops;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param minDrops the minDrops to set
|
||||||
|
*/
|
||||||
|
public void setMinDrops(Integer minDrops) {
|
||||||
|
this.minDrops = minDrops;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the blockId
|
||||||
|
*/
|
||||||
|
public Identifier getBlockId() {
|
||||||
|
return blockId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param blockId the blockId to set
|
||||||
|
*/
|
||||||
|
public void setBlockId(Identifier blockId) {
|
||||||
|
this.blockId = blockId;
|
||||||
|
}
|
||||||
|
}
|
||||||
54
src/main/java/de/jottyfan/minecraft/item/QPickaxe.java
Normal file
54
src/main/java/de/jottyfan/minecraft/item/QPickaxe.java
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
package de.jottyfan.minecraft.item;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
import net.minecraft.tags.BlockTags;
|
||||||
|
import net.minecraft.tags.ItemTags;
|
||||||
|
import net.minecraft.world.item.Item;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.ToolMaterial;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class QPickaxe extends Item implements ToolRangeable {
|
||||||
|
private HarvestRange range;
|
||||||
|
|
||||||
|
public QPickaxe(QIP properties) {
|
||||||
|
super(properties.pickaxe(new ToolMaterial(BlockTags.INCORRECT_FOR_DIAMOND_TOOL, properties.getDurability(), 7.0F, 1.0F, 15, ItemTags.DIAMOND_TOOL_MATERIALS), 7F, -3.1F));
|
||||||
|
this.range = properties.getHarvestRange();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HarvestRange getRange(ItemStack stack) {
|
||||||
|
return range;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canBreakNeighbors(BlockState blockIn) {
|
||||||
|
return new ItemStack(this).isCorrectToolForDrops(blockIn);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Block> getBlockList(Block block) {
|
||||||
|
return Lists.newArrayList(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Override
|
||||||
|
// public ActionResult<ItemStack> onItemRightClick(World worldIn, PlayerEntity playerIn, Hand handIn) {
|
||||||
|
// CommonToolCode.onItemRightClick(worldIn, playerIn, handIn);
|
||||||
|
// return super.onItemRightClick(worldIn, playerIn, handIn);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Override
|
||||||
|
// public void addInformation(ItemStack stack, World worldIn, List<ITextComponent> tooltip, ITooltipFlag flagIn) {
|
||||||
|
// CommonToolCode.addInformation(stack, worldIn, tooltip, flagIn);
|
||||||
|
// super.addInformation(stack, worldIn, tooltip, flagIn);
|
||||||
|
// }
|
||||||
|
}
|
||||||
99
src/main/java/de/jottyfan/minecraft/item/QShears.java
Normal file
99
src/main/java/de/jottyfan/minecraft/item/QShears.java
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
package de.jottyfan.minecraft.item;
|
||||||
|
|
||||||
|
import net.minecraft.core.component.DataComponents;
|
||||||
|
import net.minecraft.world.InteractionHand;
|
||||||
|
import net.minecraft.world.InteractionResult;
|
||||||
|
import net.minecraft.world.entity.LivingEntity;
|
||||||
|
import net.minecraft.world.entity.animal.chicken.Chicken;
|
||||||
|
import net.minecraft.world.entity.animal.cow.Cow;
|
||||||
|
import net.minecraft.world.entity.animal.equine.Horse;
|
||||||
|
import net.minecraft.world.entity.animal.sheep.Sheep;
|
||||||
|
import net.minecraft.world.entity.item.ItemEntity;
|
||||||
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
import net.minecraft.world.item.DyeColor;
|
||||||
|
import net.minecraft.world.item.Item;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.Items;
|
||||||
|
import net.minecraft.world.item.ShearsItem;
|
||||||
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class QShears extends ShearsItem {
|
||||||
|
private final Integer minimum;
|
||||||
|
|
||||||
|
public QShears(QIP properties) {
|
||||||
|
super(properties.component(DataComponents.TOOL, ShearsItem.createToolProperties()));
|
||||||
|
this.minimum = properties.getMinDrops();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InteractionResult interactLivingEntity(ItemStack stack, Player user, LivingEntity entity,
|
||||||
|
InteractionHand hand) {
|
||||||
|
Vec3 pos = entity.position();
|
||||||
|
Integer amount = minimum + entity.getRandom().nextInt(4);
|
||||||
|
if (entity instanceof Sheep sheep) {
|
||||||
|
if (!sheep.isSheared()) {
|
||||||
|
sheep.setSheared(true);
|
||||||
|
sheep.playAmbientSound();
|
||||||
|
DyeColor color = sheep.getColor();
|
||||||
|
Item item = Items.WHITE_WOOL;
|
||||||
|
if (color.equals(DyeColor.BLACK)) {
|
||||||
|
item = Items.BLACK_WOOL;
|
||||||
|
} else if (color.equals(DyeColor.GRAY)) {
|
||||||
|
item = Items.GRAY_WOOL;
|
||||||
|
} else if (color.equals(DyeColor.LIGHT_GRAY)) {
|
||||||
|
item = Items.LIGHT_GRAY_WOOL;
|
||||||
|
} else if (color.equals(DyeColor.BROWN)) {
|
||||||
|
item = Items.BROWN_WOOL;
|
||||||
|
} else if (color.equals(DyeColor.BLUE)) {
|
||||||
|
item = Items.BLUE_WOOL;
|
||||||
|
} else if (color.equals(DyeColor.LIGHT_BLUE)) {
|
||||||
|
item = Items.LIGHT_BLUE_WOOL;
|
||||||
|
} else if (color.equals(DyeColor.GREEN)) {
|
||||||
|
item = Items.GREEN_WOOL;
|
||||||
|
} else if (color.equals(DyeColor.LIME)) {
|
||||||
|
item = Items.LIME_WOOL;
|
||||||
|
} else if (color.equals(DyeColor.CYAN)) {
|
||||||
|
item = Items.CYAN_WOOL;
|
||||||
|
} else if (color.equals(DyeColor.MAGENTA)) {
|
||||||
|
item = Items.MAGENTA_WOOL;
|
||||||
|
} else if (color.equals(DyeColor.ORANGE)) {
|
||||||
|
item = Items.ORANGE_WOOL;
|
||||||
|
} else if (color.equals(DyeColor.PINK)) {
|
||||||
|
item = Items.PINK_WOOL;
|
||||||
|
} else if (color.equals(DyeColor.PURPLE)) {
|
||||||
|
item = Items.PURPLE_WOOL;
|
||||||
|
} else if (color.equals(DyeColor.RED)) {
|
||||||
|
item = Items.RED_WOOL;
|
||||||
|
} else if (color.equals(DyeColor.YELLOW)) {
|
||||||
|
item = Items.YELLOW_WOOL;
|
||||||
|
}
|
||||||
|
user.level().addFreshEntity(new ItemEntity(user.level(), pos.x, pos.y, pos.z, new ItemStack(item, amount)));
|
||||||
|
return InteractionResult.SUCCESS;
|
||||||
|
}
|
||||||
|
} else if (entity instanceof Horse horse) {
|
||||||
|
horse.playAmbientSound();
|
||||||
|
horse.setBaby(true);
|
||||||
|
user.level()
|
||||||
|
.addFreshEntity(new ItemEntity(user.level(), pos.x, pos.y, pos.z, new ItemStack(Items.LEATHER, amount)));
|
||||||
|
return InteractionResult.SUCCESS;
|
||||||
|
} else if (entity instanceof Cow cow) {
|
||||||
|
cow.playAmbientSound();
|
||||||
|
cow.setBaby(true);
|
||||||
|
user.level()
|
||||||
|
.addFreshEntity(new ItemEntity(user.level(), pos.x, pos.y, pos.z, new ItemStack(Items.LEATHER, amount)));
|
||||||
|
return InteractionResult.SUCCESS;
|
||||||
|
} else if (entity instanceof Chicken chicken) {
|
||||||
|
chicken.playAmbientSound();
|
||||||
|
chicken.setBaby(true);
|
||||||
|
user.level()
|
||||||
|
.addFreshEntity(new ItemEntity(user.level(), pos.x, pos.y, pos.z, new ItemStack(Items.FEATHER, amount)));
|
||||||
|
return InteractionResult.SUCCESS;
|
||||||
|
}
|
||||||
|
return InteractionResult.PASS;
|
||||||
|
}
|
||||||
|
}
|
||||||
83
src/main/java/de/jottyfan/minecraft/item/QShovel.java
Normal file
83
src/main/java/de/jottyfan/minecraft/item/QShovel.java
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
package de.jottyfan.minecraft.item;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.tags.BlockTags;
|
||||||
|
import net.minecraft.tags.ItemTags;
|
||||||
|
import net.minecraft.world.InteractionResult;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.ShovelItem;
|
||||||
|
import net.minecraft.world.item.ToolMaterial;
|
||||||
|
import net.minecraft.world.item.context.UseOnContext;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.Blocks;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
|
||||||
|
public class QShovel extends ShovelItem implements ToolRangeable {
|
||||||
|
public HarvestRange range;
|
||||||
|
|
||||||
|
public QShovel(QIP properties) {
|
||||||
|
super(new ToolMaterial(BlockTags.INCORRECT_FOR_DIAMOND_TOOL, properties.getDurability(), 7f, 1f, 15, ItemTags.DIAMOND_TOOL_MATERIALS), 7F, -3.1F, properties);
|
||||||
|
this.range = properties.getHarvestRange();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createPathOnGrass(Level level, BlockPos pos, Direction side) {
|
||||||
|
BlockState blockState = level.getBlockState(pos);
|
||||||
|
if (blockState.isAir()) {
|
||||||
|
// try to find one underneath
|
||||||
|
pos = pos.below();
|
||||||
|
blockState = level.getBlockState(pos);
|
||||||
|
} else if (!level.getBlockState(pos.above()).isAir()) {
|
||||||
|
pos = pos.above();
|
||||||
|
blockState = level.getBlockState(pos);
|
||||||
|
}
|
||||||
|
if (side != Direction.DOWN) {
|
||||||
|
if (blockState != null && level.getBlockState(pos.above()).isAir()) {
|
||||||
|
if (!level.isClientSide()) {
|
||||||
|
level.setBlockAndUpdate(pos, Blocks.DIRT_PATH.defaultBlockState());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InteractionResult useOn(UseOnContext context) {
|
||||||
|
for (BlockPos pos : range.getRangeAsBlockPosArray(context.getClickedPos(), true, new BlockPos(1, 1, 1))) {
|
||||||
|
createPathOnGrass(context.getLevel(), pos, context.getClickedFace());
|
||||||
|
}
|
||||||
|
return super.useOn(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HarvestRange getRange(ItemStack stack) {
|
||||||
|
return range;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canBreakNeighbors(BlockState blockState) {
|
||||||
|
return new ItemStack(this).isCorrectToolForDrops(blockState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Block> getBlockList(Block block) {
|
||||||
|
return Lists.newArrayList(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Override
|
||||||
|
// public ActionResult<ItemStack> onItemRightClick(World worldIn, PlayerEntity playerIn, Hand handIn) {
|
||||||
|
// CommonToolCode.onItemRightClick(worldIn, playerIn, handIn);
|
||||||
|
// return super.onItemRightClick(worldIn, playerIn, handIn);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Override
|
||||||
|
// public void addInformation(ItemStack stack, World worldIn, List<ITextComponent> tooltip, ITooltipFlag flagIn) {
|
||||||
|
// CommonToolCode.addInformation(stack, worldIn, tooltip, flagIn);
|
||||||
|
// super.addInformation(stack, worldIn, tooltip, flagIn);
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
||||||
34
src/main/java/de/jottyfan/minecraft/item/QWaterHoe.java
Normal file
34
src/main/java/de/jottyfan/minecraft/item/QWaterHoe.java
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
package de.jottyfan.minecraft.item;
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.world.InteractionResult;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.context.UseOnContext;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.block.Blocks;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class QWaterHoe extends QHoe {
|
||||||
|
private QIP properties;
|
||||||
|
|
||||||
|
public QWaterHoe(QIP properties) {
|
||||||
|
super(properties);
|
||||||
|
this.properties = properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InteractionResult useOn(UseOnContext context) {
|
||||||
|
InteractionResult res = super.useOn(context);
|
||||||
|
if (!InteractionResult.PASS.equals(res)) {
|
||||||
|
BlockPos pos = context.getClickedPos();
|
||||||
|
Level level = context.getLevel();
|
||||||
|
level.setBlockAndUpdate(pos, Blocks.WATER.defaultBlockState());
|
||||||
|
context.getPlayer().setItemInHand(context.getHand(), new ItemStack(properties.getFallbackItem()));
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,15 +3,15 @@ package de.jottyfan.minecraft.item;
|
|||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
import de.jottyfan.minecraft.Quickly;
|
import de.jottyfan.minecraft.Quickly;
|
||||||
import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents;
|
import de.jottyfan.minecraft.name.ID;
|
||||||
import net.minecraft.core.Registry;
|
import net.minecraft.core.Registry;
|
||||||
import net.minecraft.core.registries.BuiltInRegistries;
|
import net.minecraft.core.registries.BuiltInRegistries;
|
||||||
import net.minecraft.core.registries.Registries;
|
import net.minecraft.core.registries.Registries;
|
||||||
import net.minecraft.resources.Identifier;
|
import net.minecraft.resources.Identifier;
|
||||||
import net.minecraft.resources.ResourceKey;
|
import net.minecraft.resources.ResourceKey;
|
||||||
import net.minecraft.world.item.CreativeModeTabs;
|
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraft.world.item.Item.Properties;
|
import net.minecraft.world.item.equipment.ArmorType;
|
||||||
|
import net.minecraft.world.level.ItemLike;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -19,39 +19,95 @@ import net.minecraft.world.item.Item.Properties;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class QuicklyItems {
|
public class QuicklyItems {
|
||||||
public static final Item STUB = registerItem("stub", properties -> new Stub(properties));
|
public static final Item STUB = registerItem(ID.STUB, Stub::new);
|
||||||
public static final Item RAWTURQUOISE = registerItem("rawturquoise");
|
public static final Item RAWTURQUOISE = registerItem(ID.RAWTURQUOISE);
|
||||||
public static final Item TURQUOISEINGOT = registerItem("turquoiseingot");
|
public static final Item TURQUOISEINGOT = registerItem(ID.TURQUOISEINGOT);
|
||||||
public static final Item COTTON = registerItem("cotton");
|
public static final Item COTTON = registerItem(ID.COTTON);
|
||||||
public static final Item COTTONPLANT = registerItem("cottonplant");
|
public static final Item COTTONPLANT = registerItem(ID.COTTONPLANT);
|
||||||
public static final Item COTTONSEED = registerItem("cottonseed", properties -> new Plant(properties, "blockcottonplant"));
|
public static final Item COTTONSEED = registerItem(ID.COTTONSEED, QIP.of(ID.BLOCKCOTTONPLANT), Plant::new);
|
||||||
|
public static final Item CANOLA = registerItem(ID.CANOLA);
|
||||||
|
public static final Item CANOLAPLANT = registerItem(ID.CANOLAPLANT);
|
||||||
|
public static final Item CANOLASEED = registerItem(ID.CANOLASEED, QIP.of(ID.BLOCKCANOLAPLANT), Plant::new);
|
||||||
|
public static final Item CANOLABOTTLE = registerItem(ID.CANOLABOTTLE);
|
||||||
|
public static final Item CANOLABOTTLESTACK = registerItem(ID.CANOLABOTTLESTACK);
|
||||||
|
public static final Item ROTTENFLESHSTRIPES = registerItem(ID.ROTTEN_FLESH_STRIPES);
|
||||||
|
public static final Item OXIDIZEDCOPPERPOWDER = registerItem(ID.OXIDIZEDCOPPERPOWDER);
|
||||||
|
public static final Item COPPERSTRING = registerItem(ID.COPPERSTRING);
|
||||||
|
public static final Item COPPERPOWDER = registerItem(ID.COPPERPOWDER);
|
||||||
|
public static final Item COPPERSTUB = registerItem(ID.COPPERSTUB);
|
||||||
|
public static final Item COPPERSTICK = registerItem(ID.COPPERSTICK);
|
||||||
|
public static final Item SPEEDPOWDER = registerItem(ID.SPEEDPOWDER);
|
||||||
|
public static final Item QUICKIEPOWDER = registerItem(ID.QUICKIEPOWDER);
|
||||||
|
public static final Item SPEEDINGOT = registerItem(ID.SPEEDINGOT);
|
||||||
|
public static final Item QUICKIEINGOT = registerItem(ID.QUICKIEINGOT);
|
||||||
|
public static final Item MAGNIFIER = registerItem(ID.MAGNIFIER);
|
||||||
|
public static final Item SALPETER = registerItem(ID.SALPETER);
|
||||||
|
public static final Item SULFOR = registerItem(ID.SULFOR);
|
||||||
|
public static final Item CARROTSTACK = registerItem(ID.CARROTSTACK);
|
||||||
|
|
||||||
private static final Item registerItem(String name) {
|
// TODO: rename tools to speedaxe and quickaxe instead of the powder version
|
||||||
return QuicklyItems.registerItem(name, new Item.Properties());
|
|
||||||
|
// tools
|
||||||
|
private static final Integer SPEED_DURATION = 800;
|
||||||
|
private static final Integer QUICKIE_DURATION = 2400;
|
||||||
|
|
||||||
|
public static final Item SPEEDAXE = registerItem(ID.SPEEDPOWDERAXE, QIP.of(32, 64, 32, SPEED_DURATION), QAxe::new);
|
||||||
|
public static final Item SPEEDHOE = registerItem(ID.SPEEDPOWDERHOE, QIP.of(2, SPEED_DURATION), QHoe::new);
|
||||||
|
public static final Item SPEEDPICKAXE = registerItem(ID.SPEEDPOWDERPICKAXE, QIP.of(3, SPEED_DURATION), QPickaxe::new);
|
||||||
|
public static final Item SPEEDSHEARS = registerItem(ID.SPEEDPOWDERSHEARS, QIP.of(1), QShears::new);
|
||||||
|
public static final Item SPEEDSHOVEL = registerItem(ID.SPEEDPOWDERSHOVEL, QIP.of(3, SPEED_DURATION), QShovel::new);
|
||||||
|
public static final Item SPEEDWATERHOE = registerItem(ID.SPEEDPOWDERWATERHOE, QIP.of(SPEEDHOE, 2, SPEED_DURATION),
|
||||||
|
QWaterHoe::new);
|
||||||
|
public static final Item QUICKIEAXE = registerItem(ID.QUICKIEPOWDERAXE, QIP.of(64, 128, 64, QUICKIE_DURATION),
|
||||||
|
QAxe::new);
|
||||||
|
public static final Item QUICKIEHOE = registerItem(ID.QUICKIEPOWDERHOE, QIP.of(4, QUICKIE_DURATION), QHoe::new);
|
||||||
|
public static final Item QUICKIEPICKAXE = registerItem(ID.QUICKIEPOWDERPICKAXE, QIP.of(6, QUICKIE_DURATION),
|
||||||
|
QPickaxe::new);
|
||||||
|
public static final Item QUICKIESHEARS = registerItem(ID.QUICKIEPOWDERSHEARS, QIP.of(3), QShears::new);
|
||||||
|
public static final Item QUICKIESHOVEL = registerItem(ID.QUICKIEPOWDERSHOVEL, QIP.of(6, QUICKIE_DURATION),
|
||||||
|
QShovel::new);
|
||||||
|
public static final Item QUICKIEWATERHOE = registerItem(ID.QUICKIEPOWDERWATERHOE,
|
||||||
|
QIP.of(QUICKIEHOE, 4, QUICKIE_DURATION), QWaterHoe::new);
|
||||||
|
|
||||||
|
// armor
|
||||||
|
public static final Item ARMOR_TURQUOISE_BOOTS = registerItem(ID.TURQUOISE_BOOTS, ArmorType.BOOTS);
|
||||||
|
public static final Item ARMOR_TURQUOISE_HELMET = registerItem(ID.TURQUOISE_HELMET, ArmorType.HELMET);
|
||||||
|
public static final Item ARMOR_TURQUOISE_LEGGINGS = registerItem(ID.TURQUOISE_LEGGINGS, ArmorType.LEGGINGS);
|
||||||
|
public static final Item ARMOR_TURQUOISE_CHESTPLATE = registerItem(ID.TURQUOISE_CHESTPLATE, ArmorType.CHESTPLATE);
|
||||||
|
|
||||||
|
private static final Item registerItem(Identifier identifier, ArmorType armorType) {
|
||||||
|
return QuicklyItems.registerItem(identifier,
|
||||||
|
new QIP().stacksTo(1).humanoidArmor(ModArmorMaterials.TURQUOISE_ARMOR_MATERIAL, armorType));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Item registerItem(String name, Item.Properties properties) {
|
private static final Item registerItem(Identifier identifier) {
|
||||||
return QuicklyItems.registerItem(name, properties, p -> new Item(p));
|
return QuicklyItems.registerItem(identifier, new QIP());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Item registerItem(String name, Function<Properties, Item> function) {
|
private static final Item registerItem(Identifier identifier, QIP properties) {
|
||||||
return QuicklyItems.registerItem(name, new Item.Properties(), function);
|
return QuicklyItems.registerItem(identifier, properties, Item::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Item registerItem(String name, Item.Properties properties, Function<Properties, Item> function) {
|
private static final Item registerItem(Identifier identifier, Function<QIP, Item> function) {
|
||||||
Identifier identifier = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, name);
|
return QuicklyItems.registerItem(identifier, new QIP(), function);
|
||||||
Item item = function.apply(properties.setId(ResourceKey.create(Registries.ITEM, identifier)).modelId(identifier)
|
}
|
||||||
.useItemDescriptionPrefix());
|
|
||||||
|
private static final Item registerItem(Identifier identifier, QIP properties, Function<QIP, Item> function) {
|
||||||
|
Item item = function.apply(properties.setVanilla(ResourceKey.create(Registries.ITEM, identifier), identifier));
|
||||||
return Registry.register(BuiltInRegistries.ITEM, identifier, item);
|
return Registry.register(BuiltInRegistries.ITEM, identifier, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void registerModItems() {
|
public static final void registerModItems() {
|
||||||
ItemGroupEvents.modifyEntriesEvent(CreativeModeTabs.TOOLS_AND_UTILITIES).register(item -> {
|
Quickly.LOGGER.info("forbid the optimizer to ignore static item registration");
|
||||||
item.accept(STUB);
|
}
|
||||||
item.accept(RAWTURQUOISE);
|
|
||||||
item.accept(TURQUOISEINGOT);
|
/**
|
||||||
item.accept(COTTON);
|
* get the item of the identifier or null
|
||||||
item.accept(COTTONSEED);
|
*
|
||||||
});
|
* @param identifier the identifier
|
||||||
|
* @return the item or null
|
||||||
|
*/
|
||||||
|
public static final ItemLike of(Identifier identifier) {
|
||||||
|
return BuiltInRegistries.ITEM.getValue(identifier);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,19 +24,16 @@ import net.minecraft.world.level.block.Blocks;
|
|||||||
*/
|
*/
|
||||||
public class Stub extends Item {
|
public class Stub extends Item {
|
||||||
|
|
||||||
// @formatter:off
|
|
||||||
private static final Map<Block, Item> SLASH_MAP = Map.of(
|
|
||||||
Blocks.HAY_BLOCK, Items.WHEAT,
|
|
||||||
Blocks.DRIED_KELP_BLOCK, Items.DRIED_KELP,
|
|
||||||
QuicklyBlocks.KELPBUNDLE, Items.KELP);
|
|
||||||
// @formatter:on
|
|
||||||
|
|
||||||
public Stub(Properties properties) {
|
public Stub(Properties properties) {
|
||||||
super(properties.stacksTo(64));
|
super(properties.stacksTo(64));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InteractionResult useOn(UseOnContext context) {
|
public InteractionResult useOn(UseOnContext context) {
|
||||||
|
Map<Block, Item> SLASH_MAP = Map.of(
|
||||||
|
Blocks.HAY_BLOCK, Items.WHEAT,
|
||||||
|
Blocks.DRIED_KELP_BLOCK, Items.DRIED_KELP,
|
||||||
|
QuicklyBlocks.KELPBUNDLE, Items.KELP);
|
||||||
Level level = context.getLevel();
|
Level level = context.getLevel();
|
||||||
BlockPos pos = context.getClickedPos();
|
BlockPos pos = context.getClickedPos();
|
||||||
Block clickedBlock = level.getBlockState(pos).getBlock();
|
Block clickedBlock = level.getBlockState(pos).getBlock();
|
||||||
|
|||||||
39
src/main/java/de/jottyfan/minecraft/item/ToolRangeable.java
Normal file
39
src/main/java/de/jottyfan/minecraft/item/ToolRangeable.java
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
package de.jottyfan.minecraft.item;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface ToolRangeable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param stack the item stack that keeps the range
|
||||||
|
* @return range of blocks to be harvested
|
||||||
|
*/
|
||||||
|
public HarvestRange getRange(ItemStack stack);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check if this block state is one that affects the neighbor blocks to break
|
||||||
|
* also if they are from the same type
|
||||||
|
*
|
||||||
|
* @param blockState the block state of the current block
|
||||||
|
* @return true or false
|
||||||
|
*/
|
||||||
|
public boolean canBreakNeighbors(BlockState blockState);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get list of blocks that belong together (could be useful for stripped logs)
|
||||||
|
*
|
||||||
|
* @param block of the set
|
||||||
|
* @return the list of blocks or null if not found
|
||||||
|
*/
|
||||||
|
public List<Block> getBlockList(Block block);
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package de.jottyfan.minecraft.loot;
|
||||||
|
|
||||||
|
import de.jottyfan.minecraft.item.QuicklyItems;
|
||||||
|
import net.fabricmc.fabric.api.loot.v3.LootTableEvents;
|
||||||
|
import net.minecraft.resources.Identifier;
|
||||||
|
import net.minecraft.world.item.Item;
|
||||||
|
import net.minecraft.world.level.storage.loot.LootPool;
|
||||||
|
import net.minecraft.world.level.storage.loot.entries.LootItem;
|
||||||
|
import net.minecraft.world.level.storage.loot.predicates.LootItemRandomChanceCondition;
|
||||||
|
import net.minecraft.world.level.storage.loot.providers.number.ConstantValue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class QuicklyLootTables {
|
||||||
|
|
||||||
|
public static final void registerChanges() {
|
||||||
|
LootTableEvents.MODIFY.register((key, tableBuilder, source, registries) -> {
|
||||||
|
if (source.isBuiltin()) {
|
||||||
|
Identifier shortGrass = Identifier.fromNamespaceAndPath("minecraft", "blocks/short_grass");
|
||||||
|
Identifier tallGrass = Identifier.fromNamespaceAndPath("minecraft", "blocks/tall_grass");
|
||||||
|
if (key.identifier().equals(shortGrass)) {
|
||||||
|
tableBuilder.withPool(harvestItemByChance(QuicklyItems.COTTONSEED, 0.05f));
|
||||||
|
} else if (key.identifier().equals(tallGrass)) {
|
||||||
|
tableBuilder.withPool(harvestItemByChance(QuicklyItems.CANOLASEED, 0.03f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final LootPool.Builder harvestItemByChance(Item item, float chance) {
|
||||||
|
return LootPool.lootPool().setRolls(ConstantValue.exactly(1f))
|
||||||
|
.when(LootItemRandomChanceCondition.randomChance(chance)).add(LootItem.lootTableItem(item));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,20 +1,34 @@
|
|||||||
package de.jottyfan.minecraft.mixin;
|
package de.jottyfan.minecraft.mixin;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
import net.minecraft.server.MinecraftServer;
|
import de.jottyfan.minecraft.block.QuicklyBlocks;
|
||||||
|
import net.minecraft.client.renderer.ItemBlockRenderTypes;
|
||||||
|
import net.minecraft.client.renderer.chunk.ChunkSectionLayer;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author jotty
|
* @author jotty
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Mixin(MinecraftServer.class)
|
@Mixin(ItemBlockRenderTypes.class)
|
||||||
public class QuicklyMixin {
|
public class QuicklyMixin {
|
||||||
@Inject(at = @At("HEAD"), method = "loadLevel")
|
@Shadow
|
||||||
private void init(CallbackInfo info) {
|
@Final
|
||||||
|
private static Map<Block, ChunkSectionLayer> TYPE_BY_BLOCK;
|
||||||
|
|
||||||
|
@Inject(method = "<clinit>", at = @At("RETURN"))
|
||||||
|
private static void onStaticInit(CallbackInfo info) {
|
||||||
|
ChunkSectionLayer cutout = ChunkSectionLayer.CUTOUT;
|
||||||
|
TYPE_BY_BLOCK.put(QuicklyBlocks.CANOLAPLANT, cutout);
|
||||||
|
TYPE_BY_BLOCK.put(QuicklyBlocks.COTTONPLANT, cutout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
97
src/main/java/de/jottyfan/minecraft/name/ID.java
Normal file
97
src/main/java/de/jottyfan/minecraft/name/ID.java
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
package de.jottyfan.minecraft.name;
|
||||||
|
|
||||||
|
import de.jottyfan.minecraft.Quickly;
|
||||||
|
import net.minecraft.resources.Identifier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jotty
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ID {
|
||||||
|
// items
|
||||||
|
public static final Identifier STUB = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "stub");
|
||||||
|
public static final Identifier RAWTURQUOISE = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "rawturquoise");
|
||||||
|
public static final Identifier TURQUOISEINGOT = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "turquoiseingot");
|
||||||
|
public static final Identifier COTTON = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "cotton");
|
||||||
|
public static final Identifier COTTONPLANT = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "cottonplant");
|
||||||
|
public static final Identifier COTTONSEED = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "cottonseed");
|
||||||
|
public static final Identifier CANOLA = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "canola");
|
||||||
|
public static final Identifier CANOLAPLANT = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "canolaplant");
|
||||||
|
public static final Identifier CANOLASEED = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "canolaseed");
|
||||||
|
public static final Identifier CANOLABOTTLE = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "canolabottle");
|
||||||
|
public static final Identifier CANOLABOTTLESTACK = Identifier.fromNamespaceAndPath(Quickly.MOD_ID,
|
||||||
|
"canolabottlestack");
|
||||||
|
public static final Identifier ROTTEN_FLESH_STRIPES = Identifier.fromNamespaceAndPath(Quickly.MOD_ID,
|
||||||
|
"rotten_flesh_stripes");
|
||||||
|
public static final Identifier OXIDIZEDCOPPERPOWDER = Identifier.fromNamespaceAndPath(Quickly.MOD_ID,
|
||||||
|
"oxidizedcopperpowder");
|
||||||
|
public static final Identifier COPPERSTRING = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "copperstring");
|
||||||
|
public static final Identifier COPPERPOWDER = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "copperpowder");
|
||||||
|
public static final Identifier COPPERSTUB = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "copperstub");
|
||||||
|
public static final Identifier COPPERSTICK = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "copperstick");
|
||||||
|
public static final Identifier SPEEDPOWDER = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "speedpowder");
|
||||||
|
public static final Identifier QUICKIEPOWDER = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "quickiepowder");
|
||||||
|
public static final Identifier SPEEDINGOT = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "speedingot");
|
||||||
|
public static final Identifier QUICKIEINGOT = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "quickieingot");
|
||||||
|
public static final Identifier MAGNIFIER = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "magnifier");
|
||||||
|
public static final Identifier SALPETER = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "salpeter");
|
||||||
|
public static final Identifier SULFOR = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "sulfor");
|
||||||
|
public static final Identifier CARROTSTACK = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "carrotstack");
|
||||||
|
public static final Identifier SPEEDPOWDERAXE = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "speedpowderaxe");
|
||||||
|
public static final Identifier SPEEDPOWDERHOE = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "speedpowderhoe");
|
||||||
|
public static final Identifier SPEEDPOWDERPICKAXE = Identifier.fromNamespaceAndPath(Quickly.MOD_ID,
|
||||||
|
"speedpowderpickaxe");
|
||||||
|
public static final Identifier SPEEDPOWDERSHEARS = Identifier.fromNamespaceAndPath(Quickly.MOD_ID,
|
||||||
|
"speedpowdershears");
|
||||||
|
public static final Identifier SPEEDPOWDERSHOVEL = Identifier.fromNamespaceAndPath(Quickly.MOD_ID,
|
||||||
|
"speedpowdershovel");
|
||||||
|
public static final Identifier SPEEDPOWDERWATERHOE = Identifier.fromNamespaceAndPath(Quickly.MOD_ID,
|
||||||
|
"speedpowderwaterhoe");
|
||||||
|
public static final Identifier QUICKIEPOWDERAXE = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "quickiepowderaxe");
|
||||||
|
public static final Identifier QUICKIEPOWDERHOE = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "quickiepowderhoe");
|
||||||
|
public static final Identifier QUICKIEPOWDERPICKAXE = Identifier.fromNamespaceAndPath(Quickly.MOD_ID,
|
||||||
|
"quickiepowderpickaxe");
|
||||||
|
public static final Identifier QUICKIEPOWDERSHEARS = Identifier.fromNamespaceAndPath(Quickly.MOD_ID,
|
||||||
|
"quickiepowdershears");
|
||||||
|
public static final Identifier QUICKIEPOWDERSHOVEL = Identifier.fromNamespaceAndPath(Quickly.MOD_ID,
|
||||||
|
"quickiepowdershovel");
|
||||||
|
public static final Identifier QUICKIEPOWDERWATERHOE = Identifier.fromNamespaceAndPath(Quickly.MOD_ID,
|
||||||
|
"quickiepowderwaterhoe");
|
||||||
|
public static final Identifier TURQUOISE_BOOTS = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "turquoise_boots");
|
||||||
|
public static final Identifier TURQUOISE_HELMET = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "turquoise_helmet");
|
||||||
|
public static final Identifier TURQUOISE_LEGGINGS = Identifier.fromNamespaceAndPath(Quickly.MOD_ID,
|
||||||
|
"turquoise_leggings");
|
||||||
|
public static final Identifier TURQUOISE_CHESTPLATE = Identifier.fromNamespaceAndPath(Quickly.MOD_ID,
|
||||||
|
"turquoise_chestplate");
|
||||||
|
|
||||||
|
// blocks
|
||||||
|
public static final Identifier KELPBUNDLE = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "kelpbundle");
|
||||||
|
public static final Identifier BLOCKTURQUOISE = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "blockturquoise");
|
||||||
|
public static final Identifier ORETURQUOISE = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "oreturquoise");
|
||||||
|
public static final Identifier OREDEEPSLATETURQUOISE = Identifier.fromNamespaceAndPath(Quickly.MOD_ID,
|
||||||
|
"oredeepslateturquoise");
|
||||||
|
public static final Identifier BLOCKCOTTONPLANT = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "blockcottonplant");
|
||||||
|
public static final Identifier BLOCKCANOLAPLANT = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "blockcanolaplant");
|
||||||
|
public static final Identifier LAVAHOARDER = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "lavahoarder");
|
||||||
|
public static final Identifier BLOCKQUICKIEPOWDER = Identifier.fromNamespaceAndPath(Quickly.MOD_ID,
|
||||||
|
"blockquickiepowder");
|
||||||
|
public static final Identifier BLOCKSPEEDPOWDER = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "blockspeedpowder");
|
||||||
|
public static final Identifier MONSTERHOARDER = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "monsterhoarder");
|
||||||
|
public static final Identifier ITEMHOARDER = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "itemhoarder");
|
||||||
|
public static final Identifier DRILL = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "drill");
|
||||||
|
public static final Identifier BLOCKSTACKER = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "blockstacker");
|
||||||
|
public static final Identifier DIRTSALPETER = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "dirtsalpeter");
|
||||||
|
public static final Identifier SANDSALPETER = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "sandsalpeter");
|
||||||
|
public static final Identifier OREDEEPSLATESULFOR = Identifier.fromNamespaceAndPath(Quickly.MOD_ID,
|
||||||
|
"oredeepslatesulfor");
|
||||||
|
public static final Identifier ORENETHERSULFOR = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "orenethersulfor");
|
||||||
|
public static final Identifier ORESALPETER = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "oresalpeter");
|
||||||
|
public static final Identifier ORESANDSALPETER = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "oresandsalpeter");
|
||||||
|
public static final Identifier ORESULFOR = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "oresulfor");
|
||||||
|
public static final Identifier ORESPEEDPOWDER = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "orespeedpowder");
|
||||||
|
public static final Identifier OREDEEPSLATESPEEDPOWDER = Identifier.fromNamespaceAndPath(Quickly.MOD_ID,
|
||||||
|
"oredeepslatespeedpowder");
|
||||||
|
public static final Identifier BLOCKSALPETER = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "blocksalpeter");
|
||||||
|
public static final Identifier BLOCKSULFOR = Identifier.fromNamespaceAndPath(Quickly.MOD_ID, "blocksulfor");
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"variants": {
|
||||||
|
"age=0": { "model": "quickly:block/canolaplant0" },
|
||||||
|
"age=1": { "model": "quickly:block/canolaplant1" },
|
||||||
|
"age=2": { "model": "quickly:block/canolaplant2" },
|
||||||
|
"age=3": { "model": "quickly:block/canolaplant3" },
|
||||||
|
"age=4": { "model": "quickly:block/canolaplant4" },
|
||||||
|
"age=5": { "model": "quickly:block/canolaplant5" },
|
||||||
|
"age=6": { "model": "quickly:block/canolaplant6" },
|
||||||
|
"age=7": { "model": "quickly:block/canolaplant7" }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"variants": {
|
||||||
|
"": {
|
||||||
|
"model": "quickly:block/blockquickiepowder"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"variants": {
|
||||||
|
"": {
|
||||||
|
"model": "quickly:block/blocksalpeter"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"variants": {
|
||||||
|
"": {
|
||||||
|
"model": "quickly:block/blockspeedpowder"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"variants": {
|
||||||
|
"dest=up": { "model": "quickly:block/blockstackerup" },
|
||||||
|
"dest=down": { "model": "quickly:block/blockstackerdown" },
|
||||||
|
"dest=east": { "model": "quickly:block/blockstackereast" },
|
||||||
|
"dest=south": { "model": "quickly:block/blockstackersouth" },
|
||||||
|
"dest=west": { "model": "quickly:block/blockstackerwest" },
|
||||||
|
"dest=north": { "model": "quickly:block/blockstackernorth" }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"variants": {
|
||||||
|
"": {
|
||||||
|
"model": "quickly:block/blocksulfor"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"variants": {
|
||||||
|
"": {
|
||||||
|
"model": "quickly:block/dirtsalpeter"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
10
src/main/resources/assets/quickly/blockstates/drill.json
Normal file
10
src/main/resources/assets/quickly/blockstates/drill.json
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"variants": {
|
||||||
|
"facing=up": { "model": "quickly:block/drill" },
|
||||||
|
"facing=down": { "model": "quickly:block/drill" },
|
||||||
|
"facing=east": { "model": "quickly:block/drilleast" },
|
||||||
|
"facing=south": { "model": "quickly:block/drillsouth" },
|
||||||
|
"facing=west": { "model": "quickly:block/drillwest" },
|
||||||
|
"facing=north": { "model": "quickly:block/drillnorth" }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"variants": {
|
||||||
|
"": {
|
||||||
|
"model": "quickly:block/itemhoarder"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"variants": {
|
||||||
|
"filled=true": { "model": "quickly:block/lavahoarder" },
|
||||||
|
"filled=false": { "model": "quickly:block/emptylavahoarder" }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"variants": {
|
||||||
|
"": {
|
||||||
|
"model": "quickly:block/monsterhoarder"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"variants": {
|
||||||
|
"": {
|
||||||
|
"model": "quickly:block/oredeepslatespeedpowder"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"variants": {
|
||||||
|
"": {
|
||||||
|
"model": "quickly:block/oredeepslatesulfor"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"variants": {
|
||||||
|
"": {
|
||||||
|
"model": "quickly:block/orenethersulfor"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"variants": {
|
||||||
|
"": {
|
||||||
|
"model": "quickly:block/oresalpeter"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"variants": {
|
||||||
|
"": {
|
||||||
|
"model": "quickly:block/oresandsalpeter"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"variants": {
|
||||||
|
"": {
|
||||||
|
"model": "quickly:block/orespeedpowder"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"variants": {
|
||||||
|
"": {
|
||||||
|
"model": "quickly:block/oresulfor"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"variants": {
|
||||||
|
"": {
|
||||||
|
"model": "quickly:block/sandsalpeter"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
14
src/main/resources/assets/quickly/equipment/turquoise.json
Normal file
14
src/main/resources/assets/quickly/equipment/turquoise.json
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"layers": {
|
||||||
|
"humanoid": [
|
||||||
|
{
|
||||||
|
"texture": "quickly:turquoise"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"humanoid_leggings": [
|
||||||
|
{
|
||||||
|
"texture": "quickly:turquoise"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:item/blockquickiepowder"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:block/blocksalpeter"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:block/blockspeedpowder"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:block/blockstackerdown"
|
||||||
|
}
|
||||||
|
}
|
||||||
6
src/main/resources/assets/quickly/items/blocksulfor.json
Normal file
6
src/main/resources/assets/quickly/items/blocksulfor.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:block/blocksulfor"
|
||||||
|
}
|
||||||
|
}
|
||||||
6
src/main/resources/assets/quickly/items/canola.json
Normal file
6
src/main/resources/assets/quickly/items/canola.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:item/canola"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:item/canolabottle"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:item/canolabottlestack"
|
||||||
|
}
|
||||||
|
}
|
||||||
6
src/main/resources/assets/quickly/items/canolaplant.json
Normal file
6
src/main/resources/assets/quickly/items/canolaplant.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:item/canolaseed"
|
||||||
|
}
|
||||||
|
}
|
||||||
6
src/main/resources/assets/quickly/items/canolaseed.json
Normal file
6
src/main/resources/assets/quickly/items/canolaseed.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:item/canolaseed"
|
||||||
|
}
|
||||||
|
}
|
||||||
6
src/main/resources/assets/quickly/items/carrotstack.json
Normal file
6
src/main/resources/assets/quickly/items/carrotstack.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:item/carrotstack"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:item/copperpowder"
|
||||||
|
}
|
||||||
|
}
|
||||||
6
src/main/resources/assets/quickly/items/copperstick.json
Normal file
6
src/main/resources/assets/quickly/items/copperstick.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:item/copperstick"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:item/copperstring"
|
||||||
|
}
|
||||||
|
}
|
||||||
6
src/main/resources/assets/quickly/items/copperstub.json
Normal file
6
src/main/resources/assets/quickly/items/copperstub.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:item/copperstub"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:block/dirtsalpeter"
|
||||||
|
}
|
||||||
|
}
|
||||||
6
src/main/resources/assets/quickly/items/drill.json
Normal file
6
src/main/resources/assets/quickly/items/drill.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:block/drill"
|
||||||
|
}
|
||||||
|
}
|
||||||
6
src/main/resources/assets/quickly/items/itemhoarder.json
Normal file
6
src/main/resources/assets/quickly/items/itemhoarder.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:block/itemhoarder"
|
||||||
|
}
|
||||||
|
}
|
||||||
6
src/main/resources/assets/quickly/items/lavahoarder.json
Normal file
6
src/main/resources/assets/quickly/items/lavahoarder.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:block/emptylavahoarder"
|
||||||
|
}
|
||||||
|
}
|
||||||
6
src/main/resources/assets/quickly/items/magnifier.json
Normal file
6
src/main/resources/assets/quickly/items/magnifier.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:item/magnifier"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:block/monsterhoarder"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:block/oredeepslatespeedpowder"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:block/oredeepslatesulfor"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:block/orenethersulfor"
|
||||||
|
}
|
||||||
|
}
|
||||||
6
src/main/resources/assets/quickly/items/oresalpeter.json
Normal file
6
src/main/resources/assets/quickly/items/oresalpeter.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:block/oresalpeter"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:block/oresandsalpeter"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:block/orespeedpowder"
|
||||||
|
}
|
||||||
|
}
|
||||||
6
src/main/resources/assets/quickly/items/oresulfor.json
Normal file
6
src/main/resources/assets/quickly/items/oresulfor.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:block/oresulfor"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:item/oxidizedcopperpowder"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:item/quickieingot"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:item/quickiepowder"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:item/quickiepowderaxe"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:item/quickiepowderhoe"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:item/quickiepowderpickaxe"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:item/quickiepowdershears"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:item/quickiepowdershovel"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:item/quickiepowderwaterhoe"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:item/rotten_flesh_stripes"
|
||||||
|
}
|
||||||
|
}
|
||||||
6
src/main/resources/assets/quickly/items/salpeter.json
Normal file
6
src/main/resources/assets/quickly/items/salpeter.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:item/salpeter"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:block/sandsalpeter"
|
||||||
|
}
|
||||||
|
}
|
||||||
6
src/main/resources/assets/quickly/items/speedingot.json
Normal file
6
src/main/resources/assets/quickly/items/speedingot.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"model": {
|
||||||
|
"type": "minecraft:model",
|
||||||
|
"model": "quickly:item/speedingot"
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user