Skip to content

Commit

Permalink
feat(day 2): Functional Ore Dust & Notch's Wand, disables biome blending
Browse files Browse the repository at this point in the history
  • Loading branch information
sylv256 committed Oct 12, 2024
1 parent df11b69 commit 876e892
Show file tree
Hide file tree
Showing 22 changed files with 547 additions and 12 deletions.
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ var modId = project.mod_id

repositories {
mavenLocal()
mavenCentral()
}

base {
Expand Down
1 change: 1 addition & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pluginManagement {
mavenLocal()
gradlePluginPortal()
maven { url = 'https://maven.neoforged.net/releases' }
mavenCentral()
}
}

Expand Down
34 changes: 32 additions & 2 deletions src/main/java/gay/sylv/legacy_landscape/LegacyLandscape.java
Original file line number Diff line number Diff line change
@@ -1,26 +1,39 @@
package gay.sylv.legacy_landscape;

import com.mojang.logging.LogUtils;
import gay.sylv.legacy_landscape.block.LegacyBlocks;
import gay.sylv.legacy_landscape.data_attachment.LegacyAttachments;
import gay.sylv.legacy_landscape.item.LegacyItems;
import gay.sylv.legacy_landscape.tabs.CreativeTabs;
import gay.sylv.legacy_landscape.util.CallerSensitive;
import gay.sylv.legacy_landscape.util.RandomStrings;
import net.minecraft.resources.ResourceLocation;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.fml.ModContainer;
import net.neoforged.fml.common.Mod;
import net.neoforged.fml.config.ModConfig;
import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;

import java.lang.invoke.MethodHandles;

// The value here should match an entry in the META-INF/neoforge.mods.toml file
@Mod(LegacyLandscape.MOD_ID)
public class LegacyLandscape {
public final class LegacyLandscape {
// Define mod id in a common place for everything to reference
public static final String MOD_ID = "legacy_landscape";
// Directly reference a slf4j logger
private static final Logger LOGGER = LogUtils.getLogger();
private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();

// The constructor for the mod class is the first code that is run when your mod is loaded.
// FML will recognize some parameter types like IEventBus or ModContainer and pass them in automatically.
public LegacyLandscape(IEventBus modBus, ModContainer modContainer) {
LegacyBlocks.BLOCKS.register(modBus);
LegacyItems.ITEMS.register(modBus);
CreativeTabs.CREATIVE_MODE_TABS.register(modBus);
LegacyAttachments.ATTACHMENT_TYPES.register(modBus);
modBus.addListener(this::commonSetup);

// Register our mod's ModConfigSpec so that FML can create and load the config file for us
Expand All @@ -32,6 +45,23 @@ public static ResourceLocation id(String path) {
}

private void commonSetup(final FMLCommonSetupEvent event) {
LOGGER.info(RandomStrings.randomString(RandomStrings.STARTUP));
LOGGER.error(LogUtils.FATAL_MARKER, RandomStrings.randomString(RandomStrings.STARTUP));
}

@CallerSensitive
public static void init(@NotNull Class<?>... clazzArray) {
var stackWalker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
Class<?> callerClass = stackWalker.getCallerClass();
if (!callerClass.equals(LegacyLandscape.class)) {
throw new RuntimeException(new IllegalAccessException("Stop, you are not permitted to call this method! " + callerClass.getCanonicalName() + " is not allowlisted!"));
}

try {
for (Class<?> clazz : clazzArray) {
LOOKUP.ensureInitialized(clazz);
}
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package gay.sylv.legacy_landscape.block;

import gay.sylv.legacy_landscape.item.LegacyItems;
import net.minecraft.world.item.BlockItem;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockBehaviour;
Expand All @@ -8,14 +9,15 @@
import static gay.sylv.legacy_landscape.LegacyLandscape.MOD_ID;

public final class LegacyBlocks {
private static final DeferredRegister.Blocks BLOCKS = DeferredRegister.createBlocks(MOD_ID);
private static final DeferredRegister.Items ITEMS = DeferredRegister.createItems(MOD_ID);
public static final DeferredRegister.Blocks BLOCKS = DeferredRegister.createBlocks(MOD_ID);

private LegacyBlocks() {}

private static BlockItemPair<Block, BlockItem> registerSimpleBlockItem(String path, BlockBehaviour.Properties properties) {
var block = BLOCKS.registerSimpleBlock(path, properties);
return new BlockItemPair<>(
block,
ITEMS.registerSimpleBlockItem(block)
LegacyItems.ITEMS.registerSimpleBlockItem(block)
);
}
}
26 changes: 26 additions & 0 deletions src/main/java/gay/sylv/legacy_landscape/codec/LegacyCodecs.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package gay.sylv.legacy_landscape.codec;

import io.netty.buffer.ByteBuf;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.world.level.ChunkPos;
import org.jetbrains.annotations.NotNull;

public final class LegacyCodecs {
private LegacyCodecs() {}

public static final class Stream {
private Stream() {}

public static final StreamCodec<ByteBuf, ChunkPos> CHUNK_POS = new StreamCodec<>() {
@Override
public @NotNull ChunkPos decode(ByteBuf buffer) {
return new ChunkPos(buffer.readLong());
}

@Override
public void encode(ByteBuf buffer, ChunkPos chunkPos) {
buffer.writeLong(chunkPos.toLong());
}
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package gay.sylv.legacy_landscape.data_attachment;

import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.neoforged.neoforge.attachment.IAttachmentHolder;

@FunctionalInterface
public interface AttachmentPayloadSupplier<P extends CustomPacketPayload, H extends IAttachmentHolder, T> {
P of(H holder, T data);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package gay.sylv.legacy_landscape.data_attachment;

import com.mojang.logging.LogUtils;
import com.mojang.serialization.Codec;
import gay.sylv.legacy_landscape.networking.client_bound.LegacyChunkPayload;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.neoforge.attachment.AttachmentType;
import net.neoforged.neoforge.attachment.IAttachmentHolder;
import net.neoforged.neoforge.event.level.ChunkWatchEvent;
import net.neoforged.neoforge.network.PacketDistributor;
import net.neoforged.neoforge.registries.DeferredRegister;
import net.neoforged.neoforge.registries.NeoForgeRegistries;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;

import java.io.IOException;
import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.Supplier;

import static gay.sylv.legacy_landscape.LegacyLandscape.MOD_ID;

@EventBusSubscriber(
modid = MOD_ID,
bus = EventBusSubscriber.Bus.GAME
)
public final class LegacyAttachments {
public static final DeferredRegister<AttachmentType<?>> ATTACHMENT_TYPES = DeferredRegister.create(NeoForgeRegistries.ATTACHMENT_TYPES, MOD_ID);
static final Logger LOGGER = LogUtils.getLogger();

public static final Supplier<AttachmentType<Boolean>> LEGACY_CHUNK = ATTACHMENT_TYPES.register(
"legacy_chunk",
() -> AttachmentType.builder(() -> false).serialize(Codec.BOOL).build()
);

private LegacyAttachments() {}

/**
* A version of {@link ChunkAccess#setData(AttachmentType, Object)} that additionally synchronizes the chunk data with clients.
* @param level The level in which the chunk resides.
* @param chunk The chunk to set data in.
* @param attachmentType The {@link AttachmentType}.
* @param data The data {@link T}.
* @param payloadSupplier A supplier that instantiates a packet {@link P}.
* @return The previous data (if it exists) {@link Optional}&lt;{@link T}&gt;.
* @param <T> The type of data to store.
*/
public static <T, P extends CustomPacketPayload> Optional<T> setChunkData(ServerLevel level, ChunkAccess chunk, Supplier<AttachmentType<T>> attachmentType, T data, Function<T, P> payloadSupplier) {
PacketDistributor.sendToPlayersTrackingChunk(level, chunk.getPos(), payloadSupplier.apply(data));
return Optional.ofNullable(chunk.setData(attachmentType.get(), data));
}

/**
* A version of {@link ChunkAccess#removeData(AttachmentType)} that additionally synchronizes the chunk data with clients.
* @param level The level in which the chunk resides.
* @param chunk The chunk to set data in.
* @param attachmentType The {@link AttachmentType}.
* @param payloadSupplier A supplier that instantiates a packet {@link P}.
* @return The previous data (if it exists) {@link Optional}&lt;{@link T}&gt;.
* @param <T> The type of data to store.
*/
public static <T, P extends CustomPacketPayload> Optional<T> removeChunkData(ServerLevel level, ChunkAccess chunk, Supplier<AttachmentType<T>> attachmentType, Supplier<P> payloadSupplier) {
PacketDistributor.sendToPlayersTrackingChunk(level, chunk.getPos(), payloadSupplier.get());
return Optional.ofNullable(chunk.removeData(attachmentType.get()));
}

@SubscribeEvent
public static void chunkSent(ChunkWatchEvent.Sent event) {
if (event.getChunk().hasData(LegacyAttachments.LEGACY_CHUNK)) {
PacketDistributor.sendToPlayer(event.getPlayer(), new LegacyChunkPayload(event.getPos(), event.getChunk().getData(LegacyAttachments.LEGACY_CHUNK)));
}
}
}
28 changes: 28 additions & 0 deletions src/main/java/gay/sylv/legacy_landscape/datagen/LegacyDatagen.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package gay.sylv.legacy_landscape.datagen;

import net.minecraft.data.DataGenerator;
import net.minecraft.data.PackOutput;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.neoforge.common.data.ExistingFileHelper;
import net.neoforged.neoforge.data.event.GatherDataEvent;

import static gay.sylv.legacy_landscape.LegacyLandscape.MOD_ID;

@EventBusSubscriber(
modid = MOD_ID,
bus = EventBusSubscriber.Bus.MOD
)
public final class LegacyDatagen {
@SubscribeEvent
public static void gatherData(GatherDataEvent event) {
DataGenerator generator = event.getGenerator();
PackOutput output = generator.getPackOutput();
ExistingFileHelper existingFileHelper = event.getExistingFileHelper();

generator.addProvider(
event.includeClient(),
new LegacyItemModelProvider(output, existingFileHelper)
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package gay.sylv.legacy_landscape.datagen;

import gay.sylv.legacy_landscape.item.LegacyItems;
import net.minecraft.data.PackOutput;
import net.neoforged.neoforge.client.model.generators.ItemModelProvider;
import net.neoforged.neoforge.common.data.ExistingFileHelper;

import static gay.sylv.legacy_landscape.LegacyLandscape.MOD_ID;

public final class LegacyItemModelProvider extends ItemModelProvider {
public LegacyItemModelProvider(PackOutput output, ExistingFileHelper existingFileHelper) {
super(output, MOD_ID, existingFileHelper);
}

@Override
protected void registerModels() {
basicItem(LegacyItems.ORE_DUST.get());
withExistingParent(LegacyItems.NOTCH_WAND.getId().getPath(), mcLoc("blaze_rod"));
}
}
50 changes: 49 additions & 1 deletion src/main/java/gay/sylv/legacy_landscape/item/LegacyItems.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,57 @@
package gay.sylv.legacy_landscape.item;

import net.minecraft.core.component.DataComponents;
import net.minecraft.network.chat.Component;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.Rarity;
import net.minecraft.world.item.component.ItemLore;
import net.minecraft.world.item.component.Unbreakable;
import net.neoforged.neoforge.registries.DeferredItem;
import net.neoforged.neoforge.registries.DeferredRegister;

import java.util.List;

import static gay.sylv.legacy_landscape.LegacyLandscape.MOD_ID;

public final class LegacyItems {
private static final DeferredRegister.Items ITEMS = DeferredRegister.createItems(MOD_ID);
public static final DeferredRegister.Items ITEMS = DeferredRegister.createItems(MOD_ID);

public static final DeferredItem<OreDustItem> ORE_DUST = ITEMS.registerItem(
"ore_dust",
OreDustItem::new,
new Item.Properties()
.rarity(Rarity.UNCOMMON)
.stacksTo(99)
.component(
DataComponents.LORE,
new ItemLore(
List.of(
Component.translatable("lore.legacy_landscape.ore_dust.1"),
Component.translatable("lore.legacy_landscape.ore_dust.2")
)
)
)
);

public static final DeferredItem<NotchWandItem> NOTCH_WAND = ITEMS.registerItem(
"notch_wand",
NotchWandItem::new,
new Item.Properties()
.rarity(Rarity.UNCOMMON)
.stacksTo(1)
.component(
DataComponents.LORE,
new ItemLore(
List.of(
Component.translatable("lore.legacy_landscape.notch_wand.1")
)
)
)
.component(
DataComponents.UNBREAKABLE,
new Unbreakable(true)
)
);

private LegacyItems() {}
}
40 changes: 40 additions & 0 deletions src/main/java/gay/sylv/legacy_landscape/item/NotchWandItem.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package gay.sylv.legacy_landscape.item;

import gay.sylv.legacy_landscape.data_attachment.LegacyAttachments;
import gay.sylv.legacy_landscape.networking.client_bound.LegacyChunkPayload;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.LevelChunk;
import org.jetbrains.annotations.NotNull;

import java.util.Objects;

public class NotchWandItem extends Item {
public NotchWandItem(Properties properties) {
super(properties);
}

@Override
public @NotNull InteractionResult useOn(UseOnContext context) {
BlockState state = context.getLevel().getBlockState(context.getClickedPos());
if (state.isAir()) return InteractionResult.PASS;

context.getLevel().playSound(context.getPlayer(), Objects.requireNonNull(context.getPlayer()), SoundEvents.END_PORTAL_SPAWN, SoundSource.PLAYERS, 0.25F, 3.0F);
if (!context.getLevel().isClientSide()) {
LevelChunk chunk = context.getLevel().getChunkAt(context.getClickedPos());
LegacyAttachments.removeChunkData(
(ServerLevel) context.getLevel(),
chunk,
LegacyAttachments.LEGACY_CHUNK,
() -> new LegacyChunkPayload(chunk.getPos(), false)
);
}

return InteractionResult.sidedSuccess(context.getLevel().isClientSide());
}
}
Loading

0 comments on commit 876e892

Please sign in to comment.