Implement shrine to reset skillpoints, custom shrine model, worldgen for the shrine, and other stuff
This commit is contained in:
@@ -3,6 +3,7 @@ package net.fretux.ascend;
|
||||
import net.fretux.ascend.command.AscendCommand;
|
||||
import net.fretux.ascend.config.AscendConfig;
|
||||
import net.fretux.ascend.network.PacketHandler;
|
||||
import net.fretux.ascend.registry.ModBlocks;
|
||||
import net.fretux.ascend.registry.ModItems;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
@@ -24,6 +25,7 @@ public class AscendMod {
|
||||
System.out.println("[Ascend] Mod loaded! Side=" + FMLEnvironment.dist);
|
||||
net.minecraftforge.fml.ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, AscendConfig.COMMON_SPEC);
|
||||
ModItems.register(modBus);
|
||||
ModBlocks.register(modBus);
|
||||
}
|
||||
|
||||
private void onCommonSetup(final FMLCommonSetupEvent event) {
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
package net.fretux.ascend.block;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.RenderShape;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public class ShrineOfRemembranceBlock extends Block {
|
||||
public ShrineOfRemembranceBlock(Properties props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RenderShape getRenderShape(BlockState state) {
|
||||
return RenderShape.MODEL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResult use(BlockState state, Level level, BlockPos pos,
|
||||
Player player, InteractionHand hand,
|
||||
net.minecraft.world.phys.BlockHitResult hit) {
|
||||
if (level.isClientSide) {
|
||||
net.minecraft.client.Minecraft.getInstance().setScreen(new net.fretux.ascend.client.screen.ShrineScreen());
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
return InteractionResult.CONSUME;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package net.fretux.ascend.client.screen;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import net.fretux.ascend.network.PacketHandler;
|
||||
import net.fretux.ascend.network.ServerboundShrineChoicePacket;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
||||
public class ShrineScreen extends Screen {
|
||||
|
||||
private static final int WIDTH = 200;
|
||||
private static final int HEIGHT = 120;
|
||||
|
||||
private int leftPos;
|
||||
private int topPos;
|
||||
|
||||
public ShrineScreen() {
|
||||
super(Component.literal("Shrine of Remembrance"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
super.init();
|
||||
this.leftPos = (this.width - WIDTH) / 2;
|
||||
this.topPos = (this.height - HEIGHT) / 2;
|
||||
|
||||
this.clearWidgets();
|
||||
|
||||
// Dialogue text
|
||||
int buttonY = topPos + 60;
|
||||
|
||||
Button forgetButton = Button.builder(Component.literal("I WISH TO FORGET"), (btn) -> {
|
||||
PacketHandler.INSTANCE.sendToServer(new ServerboundShrineChoicePacket("forget"));
|
||||
Minecraft.getInstance().setScreen(null);
|
||||
}).bounds(leftPos + 20, buttonY, WIDTH - 40, 20).build();
|
||||
|
||||
Button cancelButton = Button.builder(Component.literal("LEAVE"), (btn) -> {
|
||||
Minecraft.getInstance().setScreen(null);
|
||||
}).bounds(leftPos + 20, buttonY + 25, WIDTH - 40, 20).build();
|
||||
|
||||
addRenderableWidget(forgetButton);
|
||||
addRenderableWidget(cancelButton);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(GuiGraphics gui, int mouseX, int mouseY, float partialTicks) {
|
||||
this.renderBackground(gui);
|
||||
RenderSystem.enableBlend();
|
||||
gui.fill(leftPos - 6, topPos - 6, leftPos + WIDTH + 6, topPos + HEIGHT + 6, 0xAA000000);
|
||||
RenderSystem.disableBlend();
|
||||
|
||||
gui.drawCenteredString(this.font, "SPEAK, LITTLE ONE.", this.width / 2, topPos + 10, 0xAA55FF);
|
||||
gui.drawCenteredString(this.font, "WHAT IS IT YOU SEEK TO UNMAKE?", this.width / 2, topPos + 25, 0xAA55FF);
|
||||
|
||||
super.render(gui, mouseX, mouseY, partialTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPauseScreen() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -25,13 +25,13 @@ public class AscendConfig {
|
||||
builder.push("Ascend Progression");
|
||||
|
||||
xpPerMobKill = builder.comment("Ascend XP gained for killing a mob.")
|
||||
.defineInRange("xpPerMobKill", 5, 0, 1000);
|
||||
.defineInRange("xpPerMobKill", 10, 0, 1000);
|
||||
xpPerBlockBreak = builder.comment("Ascend XP gained for breaking a block (ore/stone/log).")
|
||||
.defineInRange("xpPerBlockBreak", 2, 0, 1000);
|
||||
xpPerCraft = builder.comment("Ascend XP gained for crafting items.")
|
||||
.defineInRange("xpPerCraft", 3, 0, 1000);
|
||||
.defineInRange("xpPerCraft", 1, 0, 1000);
|
||||
xpPerSmelt = builder.comment("Ascend XP gained for smelting items.")
|
||||
.defineInRange("xpPerSmelt", 2, 0, 1000);
|
||||
.defineInRange("xpPerSmelt", 1, 0, 1000);
|
||||
xpPerTrade = builder.comment("Ascend XP gained for trading with villagers.")
|
||||
.defineInRange("xpPerTrade", 5, 0, 1000);
|
||||
xpPerDamageTaken = builder.comment("Ascend XP gained for taking damage.")
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package net.fretux.ascend.datagen;
|
||||
|
||||
import net.fretux.ascend.AscendMod;
|
||||
import net.fretux.ascend.worldgen.ModWorldGenProvider;
|
||||
import net.minecraft.data.DataGenerator;
|
||||
import net.minecraft.data.PackOutput;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.common.data.ExistingFileHelper;
|
||||
@@ -14,11 +17,13 @@ public class AscendDataGenerators {
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
@SubscribeEvent
|
||||
public static void gatherData(GatherDataEvent event) {
|
||||
var generator = event.getGenerator();
|
||||
ExistingFileHelper existingFileHelper = event.getExistingFileHelper();
|
||||
DataGenerator generator = event.getGenerator();
|
||||
PackOutput output = generator.getPackOutput();
|
||||
ExistingFileHelper helper = event.getExistingFileHelper();
|
||||
|
||||
if (event.includeClient()) {
|
||||
generator.addProvider(true, new AscendItemModelProvider(generator.getPackOutput(), existingFileHelper));
|
||||
}
|
||||
generator.addProvider(event.includeClient(), new ModBlockStateProvider(output, helper));
|
||||
generator.addProvider(event.includeClient(), new AscendItemModelProvider(output, helper));
|
||||
generator.addProvider(event.includeServer(), new ModLootTableProvider(output));
|
||||
generator.addProvider(event.includeServer(), new ModWorldGenProvider(output, event.getLookupProvider()));
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package net.fretux.ascend.datagen;
|
||||
|
||||
import net.fretux.ascend.AscendMod;
|
||||
import net.fretux.ascend.registry.ModBlocks;
|
||||
import net.fretux.ascend.registry.ModItems;
|
||||
import net.minecraft.data.PackOutput;
|
||||
import net.minecraftforge.client.model.generators.ItemModelProvider;
|
||||
@@ -18,6 +19,8 @@ public class AscendItemModelProvider extends ItemModelProvider {
|
||||
protected void registerModels() {
|
||||
assert ModItems.MOONSEYE_TOME.getId() != null;
|
||||
basicItem(ModItems.MOONSEYE_TOME.getId().getPath());
|
||||
withExistingParent(ModBlocks.SHRINE_OF_REMEMBRANCE.getId().getPath(),
|
||||
modLoc("block/" + ModBlocks.SHRINE_OF_REMEMBRANCE.getId().getPath()));
|
||||
}
|
||||
|
||||
private void basicItem(String name) {
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package net.fretux.ascend.datagen;
|
||||
|
||||
import net.fretux.ascend.registry.ModBlocks;
|
||||
import net.minecraft.data.loot.BlockLootSubProvider;
|
||||
import net.minecraft.world.flag.FeatureFlags;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class ModBlockLootProvider extends BlockLootSubProvider {
|
||||
|
||||
public ModBlockLootProvider() {
|
||||
super(Set.of(), FeatureFlags.REGISTRY.allFlags());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generate() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Iterable<net.minecraft.world.level.block.Block> getKnownBlocks() {
|
||||
return Set.of(ModBlocks.SHRINE_OF_REMEMBRANCE.get());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package net.fretux.ascend.datagen;
|
||||
|
||||
import net.fretux.ascend.AscendMod;
|
||||
import net.fretux.ascend.registry.ModBlocks;
|
||||
import net.minecraft.data.PackOutput;
|
||||
import net.minecraftforge.client.model.generators.BlockStateProvider;
|
||||
import net.minecraftforge.client.model.generators.ModelFile;
|
||||
import net.minecraftforge.common.data.ExistingFileHelper;
|
||||
|
||||
public class ModBlockStateProvider extends BlockStateProvider {
|
||||
|
||||
public ModBlockStateProvider(PackOutput output, ExistingFileHelper exFileHelper) {
|
||||
super(output, AscendMod.MODID, exFileHelper);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerStatesAndModels() {
|
||||
ModelFile shrineModel = models().getExistingFile(modLoc("block/shrine_of_remembrance"));
|
||||
simpleBlockWithItem(ModBlocks.SHRINE_OF_REMEMBRANCE.get(), shrineModel);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package net.fretux.ascend.datagen;
|
||||
|
||||
import net.minecraft.data.PackOutput;
|
||||
import net.minecraft.data.loot.LootTableProvider;
|
||||
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class ModLootTableProvider extends LootTableProvider {
|
||||
public ModLootTableProvider(PackOutput output) {
|
||||
super(output, Set.of(), List.of(
|
||||
new SubProviderEntry(ModBlockLootProvider::new, LootContextParamSets.BLOCK)
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -30,5 +30,10 @@ public class PacketHandler {
|
||||
.decoder(ClientboundSyncStatsPacket::new)
|
||||
.consumerMainThread(ClientboundSyncStatsPacket::handle)
|
||||
.add();
|
||||
|
||||
INSTANCE.registerMessage(id++, ServerboundShrineChoicePacket.class,
|
||||
ServerboundShrineChoicePacket::toBytes,
|
||||
ServerboundShrineChoicePacket::new,
|
||||
ServerboundShrineChoicePacket::handle);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package net.fretux.ascend.network;
|
||||
|
||||
import net.fretux.ascend.player.PlayerStatsProvider;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraftforge.network.NetworkEvent;
|
||||
import net.minecraftforge.network.PacketDistributor;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ServerboundShrineChoicePacket {
|
||||
private final String choice;
|
||||
|
||||
public ServerboundShrineChoicePacket(String choice) {
|
||||
this.choice = choice;
|
||||
}
|
||||
|
||||
public ServerboundShrineChoicePacket(FriendlyByteBuf buf) {
|
||||
this.choice = buf.readUtf();
|
||||
}
|
||||
|
||||
public void toBytes(FriendlyByteBuf buf) {
|
||||
buf.writeUtf(choice);
|
||||
}
|
||||
|
||||
public void handle(Supplier<NetworkEvent.Context> ctx) {
|
||||
ctx.get().enqueueWork(() -> {
|
||||
ServerPlayer player = ctx.get().getSender();
|
||||
if (player == null) return;
|
||||
|
||||
player.getCapability(PlayerStatsProvider.PLAYER_STATS).ifPresent(stats -> {
|
||||
if ("forget".equals(choice)) {
|
||||
if (stats.getKnowledge() >= 15) {
|
||||
stats.addKnowledge(-15);
|
||||
stats.refundAllPoints();
|
||||
player.sendSystemMessage(Component.literal("FOOLISH... YET HONEST."));
|
||||
} else {
|
||||
player.sendSystemMessage(Component.literal("YOUR MIND IS TOO EMPTY TO BE WORTH MY TOUCH."));
|
||||
player.kill();
|
||||
}
|
||||
PlayerStatsProvider.sync(player);
|
||||
}
|
||||
});
|
||||
});
|
||||
ctx.get().setPacketHandled(true);
|
||||
}
|
||||
}
|
||||
@@ -109,6 +109,16 @@ public class PlayerStats {
|
||||
knowledge = Math.max(0, knowledge + amount);
|
||||
}
|
||||
|
||||
public void refundAllPoints() {
|
||||
int totalSpent = 0;
|
||||
for (String key : attributes.keySet()) {
|
||||
int lvl = attributes.get(key);
|
||||
totalSpent += lvl;
|
||||
attributes.put(key, 0);
|
||||
}
|
||||
unspentPoints += totalSpent;
|
||||
}
|
||||
|
||||
public boolean hasUsedMoonseye() {
|
||||
return hasUsedMoonseye;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package net.fretux.ascend.registry;
|
||||
|
||||
import net.fretux.ascend.AscendMod;
|
||||
import net.fretux.ascend.block.ShrineOfRemembranceBlock;
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
||||
import net.minecraft.world.level.material.MapColor;
|
||||
import net.minecraftforge.eventbus.api.IEventBus;
|
||||
import net.minecraftforge.registries.DeferredRegister;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
import net.minecraftforge.registries.RegistryObject;
|
||||
|
||||
public class ModBlocks {
|
||||
public static final DeferredRegister<Block> BLOCKS =
|
||||
DeferredRegister.create(ForgeRegistries.BLOCKS, AscendMod.MODID);
|
||||
|
||||
public static final RegistryObject<Block> SHRINE_OF_REMEMBRANCE = BLOCKS.register(
|
||||
"shrine_of_remembrance",
|
||||
() -> new ShrineOfRemembranceBlock(
|
||||
BlockBehaviour.Properties.of()
|
||||
.mapColor(MapColor.COLOR_PURPLE)
|
||||
.strength(-1.0F, 3600000.0F) // unbreakable
|
||||
.noLootTable()
|
||||
.lightLevel(s -> 6)
|
||||
.noOcclusion()
|
||||
.requiresCorrectToolForDrops()
|
||||
)
|
||||
);
|
||||
|
||||
public static void register(IEventBus bus) {
|
||||
BLOCKS.register(bus);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package net.fretux.ascend.worldgen;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import net.fretux.ascend.AscendMod;
|
||||
import net.fretux.ascend.registry.ModBlocks;
|
||||
import net.minecraft.core.HolderLookup;
|
||||
import net.minecraft.core.RegistrySetBuilder;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.data.PackOutput;
|
||||
import net.minecraft.data.worldgen.BootstapContext;
|
||||
import net.minecraft.data.worldgen.placement.PlacementUtils;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.levelgen.GenerationStep;
|
||||
import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
|
||||
import net.minecraft.world.level.levelgen.feature.Feature;
|
||||
import net.minecraft.world.level.levelgen.feature.configurations.NoneFeatureConfiguration;
|
||||
import net.minecraft.world.level.levelgen.placement.PlacedFeature;
|
||||
import net.minecraft.world.level.levelgen.placement.RarityFilter;
|
||||
import net.minecraftforge.common.data.DatapackBuiltinEntriesProvider;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* Generates structure and worldgen JSON entries for the Shrine of Remembrance.
|
||||
*/
|
||||
public class ModWorldGenProvider extends DatapackBuiltinEntriesProvider {
|
||||
public static final ResourceKey<ConfiguredFeature<?, ?>> SHRINE_CONFIGURED =
|
||||
ResourceKey.create(Registries.CONFIGURED_FEATURE, new ResourceLocation(AscendMod.MODID, "shrine_of_remembrance"));
|
||||
public static final ResourceKey<PlacedFeature> SHRINE_PLACED =
|
||||
ResourceKey.create(Registries.PLACED_FEATURE, new ResourceLocation(AscendMod.MODID, "shrine_of_remembrance"));
|
||||
|
||||
public ModWorldGenProvider(PackOutput output, CompletableFuture<HolderLookup.Provider> registries) {
|
||||
super(output, registries, new RegistrySetBuilder()
|
||||
.add(Registries.CONFIGURED_FEATURE, ModWorldGenProvider::bootstrapConfigured)
|
||||
.add(Registries.PLACED_FEATURE, ModWorldGenProvider::bootstrapPlaced),
|
||||
Set.of(AscendMod.MODID));
|
||||
}
|
||||
|
||||
private static void bootstrapConfigured(BootstapContext<ConfiguredFeature<?, ?>> ctx) {
|
||||
ctx.register(SHRINE_CONFIGURED,
|
||||
new ConfiguredFeature<>(Feature.NO_OP, NoneFeatureConfiguration.INSTANCE));
|
||||
}
|
||||
|
||||
private static void bootstrapPlaced(BootstapContext<PlacedFeature> ctx) {
|
||||
var configured = ctx.lookup(Registries.CONFIGURED_FEATURE).getOrThrow(SHRINE_CONFIGURED);
|
||||
ctx.register(SHRINE_PLACED,
|
||||
new PlacedFeature(configured, List.of(
|
||||
RarityFilter.onAverageOnceEvery(400) // roughly like mineshafts
|
||||
)));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user