Skip to content

Commit

Permalink
add relic altar
Browse files Browse the repository at this point in the history
  • Loading branch information
MoriyaShiine committed Jun 12, 2024
1 parent 0b19734 commit 2a34620
Show file tree
Hide file tree
Showing 23 changed files with 1,008 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"type": "minecraft:block",
"pools": [
{
"bonus_rolls": 0.0,
"conditions": [
{
"condition": "minecraft:survives_explosion"
}
],
"entries": [
{
"type": "minecraft:item",
"name": "lostrelics:jungle_altar"
}
],
"rolls": 1.0
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"values": [
"lostrelics:jungle_altar"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"values": [
"lostrelics:jungle_altar"
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@

import dev.emi.trinkets.api.client.TrinketRendererRegistry;
import moriyashiine.lostrelics.client.packet.SyncDoppelgangerSlimStatusS2CPayload;
import moriyashiine.lostrelics.client.render.blockentity.AltarBlockEntityRenderer;
import moriyashiine.lostrelics.client.render.entity.DoppelgangerEntityRenderer;
import moriyashiine.lostrelics.client.render.entity.SmokeBallEntityRenderer;
import moriyashiine.lostrelics.client.render.entity.TaintedBloodCrystalEntityRenderer;
import moriyashiine.lostrelics.client.render.model.entity.RelicSkeletonModel;
import moriyashiine.lostrelics.client.render.model.trinket.FaceTrinketRenderer;
import moriyashiine.lostrelics.client.render.model.trinket.NecklaceTrinketRenderer;
import moriyashiine.lostrelics.common.LostRelics;
import moriyashiine.lostrelics.common.init.ModBlockEntityTypes;
import moriyashiine.lostrelics.common.init.ModEntityTypes;
import moriyashiine.lostrelics.common.init.ModItems;
import moriyashiine.lostrelics.common.item.RelicItem;
Expand All @@ -21,6 +23,7 @@
import net.fabricmc.fabric.api.client.rendering.v1.EntityModelLayerRegistry;
import net.fabricmc.fabric.api.client.rendering.v1.EntityRendererRegistry;
import net.minecraft.client.item.ModelPredicateProviderRegistry;
import net.minecraft.client.render.block.entity.BlockEntityRendererFactories;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.ChargedProjectilesComponent;
import net.minecraft.item.Items;
Expand All @@ -29,6 +32,7 @@
public class LostRelicsClient implements ClientModInitializer {
@Override
public void onInitializeClient() {
BlockEntityRendererFactories.register(ModBlockEntityTypes.ALTAR, ctx -> new AltarBlockEntityRenderer());
ModelPredicateProviderRegistry.register(ModItems.TURQUOISE_EYE, new Identifier("broken"), (stack, world, entity, seed) -> RelicItem.isUsable(stack) ? 0 : 1);
ModelPredicateProviderRegistry.register(ModItems.SMOKING_MIRROR, new Identifier("broken"), (stack, world, entity, seed) -> RelicItem.isUsable(stack) ? 0 : 1);
ModelPredicateProviderRegistry.register(ModItems.TRIPLE_TOOTHED_SNAKE, new Identifier("one"), (stack, world, entity, seed) -> RelicItem.isUsable(stack) && TripleToothedSnakeItem.getCharges(stack) == 1 ? 1 : 0);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright (c) MoriyaShiine. All Rights Reserved.
*/
package moriyashiine.lostrelics.client.render.blockentity;

import moriyashiine.lostrelics.common.blockentity.AltarBlockEntity;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.block.entity.BlockEntityRenderer;
import net.minecraft.client.render.model.json.ModelTransformationMode;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.math.RotationAxis;

public class AltarBlockEntityRenderer implements BlockEntityRenderer<AltarBlockEntity> {
private static final MinecraftClient mc = MinecraftClient.getInstance();

@Override
public void render(AltarBlockEntity entity, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay) {
matrices.translate(0.5, 1.25, 0.5);
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(mc.world.getTime() * 4 + tickDelta));
mc.getItemRenderer().renderItem(null, entity.getStack(), ModelTransformationMode.GROUND, false, matrices, vertexConsumers, mc.world, light, overlay, 0);
}
}
2 changes: 2 additions & 0 deletions src/main/java/moriyashiine/lostrelics/common/LostRelics.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ public class LostRelics implements ModInitializer {

@Override
public void onInitialize() {
ModBlocks.init();
ModBlockEntityTypes.init();
ModDataComponentTypes.init();
ModEntityTypes.init();
ModItems.init();
Expand Down
135 changes: 135 additions & 0 deletions src/main/java/moriyashiine/lostrelics/common/block/AltarBlock.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/*
* Copyright (c) MoriyaShiine. All Rights Reserved.
*/
package moriyashiine.lostrelics.common.block;

import com.mojang.serialization.MapCodec;
import moriyashiine.lostrelics.common.blockentity.AltarBlockEntity;
import moriyashiine.lostrelics.common.init.ModSoundEvents;
import moriyashiine.lostrelics.common.tag.ModItemTags;
import net.minecraft.block.*;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemPlacementContext;
import net.minecraft.item.ItemStack;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.registry.Registries;
import net.minecraft.registry.tag.TagKey;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents;
import net.minecraft.state.StateManager;
import net.minecraft.util.Hand;
import net.minecraft.util.ItemActionResult;
import net.minecraft.util.ItemScatterer;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;

public class AltarBlock extends HorizontalFacingBlock implements BlockEntityProvider {
private static final MapCodec<AltarBlock> CODEC = createCodec(AltarBlock::new);

private static final VoxelShape SHAPE = createCuboidShape(0.5, 0, 0.5, 15.5, 15, 15.5);

public final TagKey<Item> relicTag;

public AltarBlock(Settings settings, TagKey<Item> relicTag) {
super(settings);
this.relicTag = relicTag;
setDefaultState(getDefaultState().with(FACING, Direction.NORTH));
}

public AltarBlock(Settings settings) {
this(settings, ModItemTags.RELICS);
}

@Override
protected MapCodec<? extends HorizontalFacingBlock> getCodec() {
return CODEC;
}

@Nullable
@Override
public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
return new AltarBlockEntity(pos, state);
}

@Nullable
@Override
public BlockState getPlacementState(ItemPlacementContext ctx) {
return super.getPlacementState(ctx).with(FACING, ctx.getHorizontalPlayerFacing());
}

@Override
protected VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
return SHAPE;
}

@Override
protected void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
if (!state.isOf(newState.getBlock())) {
AltarBlockEntity altarBlockEntity = (AltarBlockEntity) world.getBlockEntity(pos);
if (!altarBlockEntity.getStack().isEmpty()) {
ItemScatterer.spawn(world, pos.getX(), pos.getY(), pos.getZ(), altarBlockEntity.getStack().copyAndEmpty());
}
}
super.onStateReplaced(state, world, pos, newState, moved);
}

@Override
protected ItemActionResult onUseWithItem(ItemStack stack, BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
AltarBlockEntity altarBlockEntity = (AltarBlockEntity) world.getBlockEntity(pos);
if (altarBlockEntity.getStack().isEmpty()) {
if (stack.isIn(relicTag)) {
if (!world.isClient) {
world.playSound(null, pos, SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.BLOCKS, 1, 1);
altarBlockEntity.setStack(stack.split(1));
altarBlockEntity.markDirty();
altarBlockEntity.sync();
}
return ItemActionResult.success(world.isClient);
}
} else if (stack.isIn(relicTag)) {
if (!world.isClient) {
Item newRelic;
do {
newRelic = Registries.ITEM.getRandom(world.getRandom()).get().value();
}
while (!newRelic.getDefaultStack().isIn(relicTag) || stack.isOf(newRelic) || altarBlockEntity.getStack().isOf(newRelic));
altarBlockEntity.setStack(newRelic.getDefaultStack());
altarBlockEntity.markDirty();
altarBlockEntity.sync();
stack.decrement(1);
world.playSound(null, pos, ModSoundEvents.BLOCK_ALTAR_CONVERT, SoundCategory.BLOCKS, 1, 1);
float dX = MathHelper.nextFloat(world.getRandom(), -0.2F, 0.2F);
float dY = MathHelper.nextFloat(world.getRandom(), -0.2F, 0.2F);
float dZ = MathHelper.nextFloat(world.getRandom(), -0.2F, 0.2F);
((ServerWorld) world).spawnParticles(ParticleTypes.SMOKE, pos.getX() + 0.5, pos.getY() + 1.4, pos.getZ() + 0.5, 48, dX, dY, dZ, 0.15);
}
return ItemActionResult.success(world.isClient);
} else if (stack.isEmpty()) {
if (!world.isClient) {
world.playSound(null, pos, SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.BLOCKS, 1, 1);
ItemStack relic = altarBlockEntity.getStack().copyAndEmpty();
altarBlockEntity.markDirty();
altarBlockEntity.sync();
if (!player.giveItemStack(relic)) {
player.dropStack(relic);
}
}
return ItemActionResult.success(world.isClient);
}
return super.onUseWithItem(stack, state, world, pos, player, hand, hit);
}

@Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
builder.add(FACING);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright (c) MoriyaShiine. All Rights Reserved.
*/
package moriyashiine.lostrelics.common.blockentity;

import moriyashiine.lostrelics.common.init.ModBlockEntityTypes;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtElement;
import net.minecraft.network.listener.ClientPlayPacketListener;
import net.minecraft.network.packet.Packet;
import net.minecraft.network.packet.s2c.play.BlockEntityUpdateS2CPacket;
import net.minecraft.registry.RegistryWrapper;
import net.minecraft.util.math.BlockPos;
import org.jetbrains.annotations.Nullable;

public class AltarBlockEntity extends BlockEntity {
private ItemStack stack = ItemStack.EMPTY;

public AltarBlockEntity(BlockPos pos, BlockState state) {
super(ModBlockEntityTypes.ALTAR, pos, state);
}

@Override
protected void readNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registryLookup) {
if (nbt.contains("Stack", NbtElement.COMPOUND_TYPE)) {
stack = ItemStack.fromNbt(registryLookup, nbt.getCompound("Stack")).orElse(ItemStack.EMPTY);
} else {
stack = ItemStack.EMPTY;
}
}

@Override
protected void writeNbt(NbtCompound nbt, RegistryWrapper.WrapperLookup registryLookup) {
nbt.putBoolean("ThisIsNeededToSync", false);
if (!stack.isEmpty()) {
nbt.put("Stack", stack.encode(registryLookup));
}
}

@Override
public NbtCompound toInitialChunkDataNbt(RegistryWrapper.WrapperLookup registryLookup) {
NbtCompound nbt = super.toInitialChunkDataNbt(registryLookup);
writeNbt(nbt, registryLookup);
return nbt;
}

@Nullable
@Override
public Packet<ClientPlayPacketListener> toUpdatePacket() {
return BlockEntityUpdateS2CPacket.create(this);
}

public void sync() {
getWorld().updateListeners(getPos(), getCachedState(), getCachedState(), Block.NOTIFY_LISTENERS);
}

public ItemStack getStack() {
return stack;
}

public void setStack(ItemStack stack) {
this.stack = stack;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Copyright (c) MoriyaShiine. All Rights Reserved.
*/
package moriyashiine.lostrelics.common.init;

import moriyashiine.lostrelics.common.LostRelics;
import moriyashiine.lostrelics.common.blockentity.AltarBlockEntity;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.datafixer.TypeReferences;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.util.Util;

public class ModBlockEntityTypes {
public static final BlockEntityType<AltarBlockEntity> ALTAR = BlockEntityType.Builder.create(AltarBlockEntity::new, ModBlocks.JUNGLE_ALTAR).build(Util.getChoiceType(TypeReferences.BLOCK_ENTITY, LostRelics.id("altar").toString()));

public static void init() {
Registry.register(Registries.BLOCK_ENTITY_TYPE, LostRelics.id("altar"), ALTAR);
}
}
22 changes: 22 additions & 0 deletions src/main/java/moriyashiine/lostrelics/common/init/ModBlocks.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright (c) MoriyaShiine. All Rights Reserved.
*/
package moriyashiine.lostrelics.common.init;

import moriyashiine.lostrelics.common.LostRelics;
import moriyashiine.lostrelics.common.block.AltarBlock;
import moriyashiine.lostrelics.common.tag.ModItemTags;
import net.minecraft.block.Block;
import net.minecraft.block.Blocks;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;

import static net.minecraft.block.AbstractBlock.Settings.copy;

public class ModBlocks {
public static Block JUNGLE_ALTAR = new AltarBlock(copy(Blocks.OBSIDIAN), ModItemTags.JUNGLE_RELICS);

public static void init() {
Registry.register(Registries.BLOCK, LostRelics.id("jungle_altar"), JUNGLE_ALTAR);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import moriyashiine.lostrelics.common.LostRelics;
import moriyashiine.lostrelics.common.item.*;
import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroup;
import net.minecraft.item.Items;
Expand All @@ -17,6 +18,8 @@
public class ModItems {
public static ItemGroup GROUP;

public static final Item JUNGLE_ALTAR = new BlockItem(ModBlocks.JUNGLE_ALTAR, new Item.Settings());

public static final Item CURSED_AMULET = new CursedAmuletItem();
public static final Item SMOKING_MIRROR = new SmokingMirrorItem();
public static final Item TRIPLE_TOOTHED_SNAKE = new TripleToothedSnakeItem();
Expand All @@ -25,13 +28,17 @@ public class ModItems {

public static void init() {
GROUP = FabricItemGroup.builder().displayName(Text.translatable("itemGroup." + LostRelics.MOD_ID)).icon(CURSED_AMULET::getDefaultStack).entries((displayContext, entries) -> {
entries.add(JUNGLE_ALTAR);
entries.add(CURSED_AMULET);
entries.add(SMOKING_MIRROR);
entries.add(TRIPLE_TOOTHED_SNAKE);
entries.add(TAINTED_BLOOD_CRYSTAL);
entries.add(TURQUOISE_EYE);
}).build();
Registry.register(Registries.ITEM_GROUP, LostRelics.id(LostRelics.MOD_ID), GROUP);

Registry.register(Registries.ITEM, LostRelics.id("jungle_altar"), JUNGLE_ALTAR);

Registry.register(Registries.ITEM, LostRelics.id("cursed_amulet"), CURSED_AMULET);
Registry.register(Registries.ITEM, LostRelics.id("smoking_mirror"), SMOKING_MIRROR);
Registry.register(Registries.ITEM, LostRelics.id("triple_toothed_snake"), TRIPLE_TOOTHED_SNAKE);
Expand Down
Loading

0 comments on commit 2a34620

Please sign in to comment.