Skip to content

Commit

Permalink
Loonium with data-driven structure loot (#4639)
Browse files Browse the repository at this point in the history
Implementation for structure detection and structure-specific loot
tables and mob spawning pools, customizable via data packs.

- structure-specific loot tables are identified by the structure ID
(e.g. for `minecraft:pillager_outpost` the custom Loonium loot table is
located at
`data/botania/loot_tables/loonium/minecraft/pillager_outpost.json`),
with a default loot table corresponding to dungeon loot (located at
`data/botania/loot_tables/loonium/default.json`)
  - default loot tables are created with Datagen
- loot tables usually just reference original chest or entity loot
tables related to each structure, so Loonium loot can be modified
separately from the loot found in those structures
- structure-specific Loonium configurations are identified the same way
(e.g. for `minecraft:pillager_outpost` the custom configuration is
located at `data/minecraft/loonium_config/pillager_outpost.json`) with a
default configuration (located at
`data/botania/loonium_config/default.json`) acting as fallback
  - default configurations are created via Datagen
- configurations can reference a parent configuration and only override
individual aspects of the referenced configuration
- configurations consist of mana cost to spawn a mob, how many mobs of
spawnable types are allowed around the flower, whether the Loonium must
be placed in the overall bounding box or an individual piece of the
structure, the weighted list of mobs to spawn, a list of potion effects
to apply to spawned mobs, and a list of attribute modifiers to apply to
the mobs
    - attribute and effect lists can be overridden for individual mobs
- custom NBT data can be defined for individual mobs (used to make a
Creeper spawn charged)
- equipment loot tables can be specified for each spawnable mob (this
will be a vanilla feature in later Minecraft versions, although the
implementation here is slightly tweaked from what Trial Chambers use)
- expanded wand HUD to indicate whether a Loonium generates
structure-specific loot
- added lexicon mention of the structure-specific behavior
- fixed the mob location selection logic to prevent mobs from
immediately starting to suffocate
- added a new challenge advancement for killing every mob type in the
structure configurations added with this change
- mobs spawned by the Loonium are put onto a unique team so they don't
just start attacking each other (because there are zoglins in some of
the mob spawn pools; Heisei Dream may need a future upgrade to support
overriding teams allegiances)

---------

Co-authored-by: Artemis System <[email protected]>
  • Loading branch information
TheRealWormbo and artemisSystem authored Oct 6, 2024
1 parent 92f4863 commit 5f4be49
Show file tree
Hide file tree
Showing 197 changed files with 12,224 additions and 142 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
import vazkii.botania.common.brew.BotaniaBrews;
import vazkii.botania.common.brew.BotaniaMobEffects;
import vazkii.botania.common.command.SkyblockCommand;
import vazkii.botania.common.config.ConfigDataManagerImpl;
import vazkii.botania.common.crafting.BotaniaRecipeTypes;
import vazkii.botania.common.entity.BotaniaEntities;
import vazkii.botania.common.entity.GaiaGuardianEntity;
Expand Down Expand Up @@ -138,6 +139,7 @@ public void onInitialize() {
PatchouliAPI.get().registerMultiblock(prefix("gaia_ritual"), GaiaGuardianEntity.ARENA_MULTIBLOCK.get());

OrechidManager.registerListener();
ConfigDataManagerImpl.registerListener();
CraftyCrateBlockEntity.registerListener();
CorporeaNodeDetectors.register(new FabricTransferCorporeaNodeDetector());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ private static void configureFabricDatagen(FabricDataGenerator.Pack pack) {

private static void configureXplatDatagen(FabricDataGenerator.Pack pack) {
pack.addProvider((PackOutput output) -> new BlockLootProvider(output));
pack.addProvider((PackOutput output) -> new LooniumStructureLootProvider(output));
pack.addProvider((PackOutput output) -> new LooniumStructureConfigurationProvider(output));
pack.addProvider(LooniumEquipmentLootProvider::new);
BlockTagProvider blockTagProvider = pack.addProvider(BlockTagProvider::new);
pack.addProvider((output, registriesFuture) -> new ItemTagProvider(output, registriesFuture, blockTagProvider.contentsGetter()));
pack.addProvider(EntityTagProvider::new);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
import dev.onyxstudios.cca.api.v3.entity.EntityComponentInitializer;
import dev.onyxstudios.cca.api.v3.entity.RespawnCopyStrategy;

import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.item.PrimedTnt;
import net.minecraft.world.entity.monster.*;
import net.minecraft.world.entity.vehicle.AbstractMinecart;

import vazkii.botania.common.block.flower.functional.LooniumBlockEntity;
import vazkii.botania.common.internal_caps.*;

import static vazkii.botania.common.lib.ResourceLocationHelper.prefix;
Expand All @@ -36,10 +36,7 @@ public class CCAInternalEntityComponents implements EntityComponentInitializer {

@Override
public void registerEntityComponentFactories(EntityComponentFactoryRegistry registry) {
for (Class<? extends Monster> clz : LooniumBlockEntity.VALID_MOBS) {
registry.registerFor(clz, LOONIUM_DROP, e -> new CCALooniumComponent());
}

registry.registerFor(Mob.class, LOONIUM_DROP, e -> new CCALooniumComponent());
registry.registerFor(PrimedTnt.class, TNT_ETHICAL, CCAEthicalComponent::new);
registry.registerFor(Slime.class, NARSLIMMUS, e -> new CCANarslimmusComponent());
registry.registerFor(ItemEntity.class, INTERNAL_ITEM, e -> new CCAItemFlagsComponent());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ private void dropEnd(DamageSource source, CallbackInfo ci) {
private void dropLoonium(DamageSource source, boolean causedByPlayer, CallbackInfo ci) {
var self = (LivingEntity) (Object) this;
LooniumBlockEntity.dropLooniumItems(self, stack -> {
self.spawnAtLocation(stack);
if (!stack.isEmpty()) {
self.spawnAtLocation(stack);
}
ci.cancel();
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@
import vazkii.botania.common.brew.BotaniaMobEffects;
import vazkii.botania.common.brew.effect.SoulCrossMobEffect;
import vazkii.botania.common.command.SkyblockCommand;
import vazkii.botania.common.config.ConfigDataManagerImpl;
import vazkii.botania.common.crafting.BotaniaRecipeTypes;
import vazkii.botania.common.entity.BotaniaEntities;
import vazkii.botania.common.entity.GaiaGuardianEntity;
Expand Down Expand Up @@ -166,6 +167,7 @@ public void commonSetup(FMLCommonSetupEvent evt) {
PatchouliAPI.get().registerMultiblock(prefix("gaia_ritual"), GaiaGuardianEntity.ARENA_MULTIBLOCK.get());

OrechidManager.registerListener();
ConfigDataManagerImpl.registerListener();
CraftyCrateBlockEntity.registerListener();
CorporeaNodeDetectors.register(new ForgeCapCorporeaNodeDetector());
if (ModList.get().isLoaded("inventorysorter")) {
Expand Down Expand Up @@ -393,9 +395,11 @@ private void registerEvents() {
});
LooniumBlockEntity.dropLooniumItems(living, stack -> {
e.getDrops().clear();
var ent = new ItemEntity(living.level(), living.getX(), living.getY(), living.getZ(), stack);
ent.setDefaultPickUpDelay();
e.getDrops().add(ent);
if (!stack.isEmpty()) {
var ent = new ItemEntity(living.level(), living.getX(), living.getY(), living.getZ(), stack);
ent.setDefaultPickUpDelay();
e.getDrops().add(ent);
}
});
});
bus.addListener((LivingDeathEvent e) -> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package vazkii.botania.forge.internal_caps;

import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.item.PrimedTnt;
import net.minecraft.world.entity.monster.Creeper;
Expand All @@ -12,7 +13,6 @@
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;

import vazkii.botania.common.block.flower.functional.LooniumBlockEntity;
import vazkii.botania.common.internal_caps.*;
import vazkii.botania.common.lib.LibMisc;
import vazkii.botania.forge.CapabilityUtil;
Expand Down Expand Up @@ -60,11 +60,8 @@ public static void attachCapabilities(AttachCapabilitiesEvent<Entity> evt) {
if (entity instanceof Player) {
evt.addCapability(prefix("kept_items"), CapabilityUtil.makeSavedProvider(KEPT_ITEMS, new KeptItemsComponent()));
}
for (Class<?> clz : LooniumBlockEntity.VALID_MOBS) {
if (clz.isInstance(entity)) {
evt.addCapability(prefix("loonium_drop"), CapabilityUtil.makeSavedProvider(LOONIUM_DROP, new LooniumComponent()));
break;
}
if (entity instanceof Mob) {
evt.addCapability(prefix("loonium_drop"), CapabilityUtil.makeSavedProvider(LOONIUM_DROP, new LooniumComponent()));
}
if (entity instanceof Slime) {
evt.addCapability(prefix("narslimmus"), CapabilityUtil.makeSavedProvider(NARSLIMMUS, new NarslimmusComponent()));
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 5f4be49

Please sign in to comment.