mirror of
https://github.com/Ellpeck/NaturesAura.git
synced 2024-11-29 14:28:33 +01:00
Compare commits
4 commits
cf275cfc09
...
4af1787320
Author | SHA1 | Date | |
---|---|---|---|
4af1787320 | |||
d73751b536 | |||
b3f2a61e5d | |||
7d23cafc77 |
55 changed files with 513 additions and 160 deletions
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"variants": {
|
||||
"": {
|
||||
"model": "naturesaura:block/lower_limiter"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"parent": "minecraft:block/cube_bottom_top",
|
||||
"textures": {
|
||||
"bottom": "naturesaura:block/lower_limiter_top",
|
||||
"side": "naturesaura:block/lower_limiter",
|
||||
"top": "naturesaura:block/lower_limiter_top"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"parent": "naturesaura:block/lower_limiter"
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:item/generated",
|
||||
"textures": {
|
||||
"layer0": "naturesaura:item/vacuum_bottle"
|
||||
}
|
||||
}
|
|
@ -1,15 +1,15 @@
|
|||
{
|
||||
"values": [
|
||||
"naturesaura:flower_generator",
|
||||
"naturesaura:ancient_log",
|
||||
"naturesaura:offering_table",
|
||||
"naturesaura:ancient_planks",
|
||||
"naturesaura:ancient_stairs",
|
||||
"naturesaura:oak_generator",
|
||||
"naturesaura:wood_stand",
|
||||
"naturesaura:ancient_bark",
|
||||
"naturesaura:ancient_slab",
|
||||
"naturesaura:nether_wart_mushroom",
|
||||
"naturesaura:auto_crafter"
|
||||
"naturesaura:oak_generator",
|
||||
"naturesaura:auto_crafter",
|
||||
"naturesaura:ancient_bark",
|
||||
"naturesaura:ancient_planks",
|
||||
"naturesaura:ancient_stairs",
|
||||
"naturesaura:flower_generator",
|
||||
"naturesaura:wood_stand",
|
||||
"naturesaura:offering_table"
|
||||
]
|
||||
}
|
|
@ -1,46 +1,47 @@
|
|||
{
|
||||
"values": [
|
||||
"naturesaura:gold_brick",
|
||||
"naturesaura:spring",
|
||||
"naturesaura:aura_detector",
|
||||
"naturesaura:infused_slab",
|
||||
"naturesaura:tainted_gold_block",
|
||||
"naturesaura:grated_chute",
|
||||
"naturesaura:snow_creator",
|
||||
"naturesaura:infused_brick",
|
||||
"naturesaura:weather_changer",
|
||||
"naturesaura:infused_brick_slab",
|
||||
"naturesaura:field_creator",
|
||||
"naturesaura:infused_stone",
|
||||
"naturesaura:time_changer",
|
||||
"naturesaura:nature_altar",
|
||||
"naturesaura:placer",
|
||||
"naturesaura:firework_generator",
|
||||
"naturesaura:infused_stairs",
|
||||
"naturesaura:projectile_generator",
|
||||
"naturesaura:item_distributor",
|
||||
"naturesaura:chunk_loader",
|
||||
"naturesaura:rf_converter",
|
||||
"naturesaura:spawn_lamp",
|
||||
"naturesaura:blast_furnace_booster",
|
||||
"naturesaura:nether_grass",
|
||||
"naturesaura:animal_container",
|
||||
"naturesaura:moss_generator",
|
||||
"naturesaura:generator_limit_remover",
|
||||
"naturesaura:pickup_stopper",
|
||||
"naturesaura:aura_timer",
|
||||
"naturesaura:animal_spawner",
|
||||
"naturesaura:ender_crate",
|
||||
"naturesaura:animal_generator",
|
||||
"naturesaura:chorus_generator",
|
||||
"naturesaura:hopper_upgrade",
|
||||
"naturesaura:furnace_heater",
|
||||
"naturesaura:potion_generator",
|
||||
"naturesaura:infused_brick_stairs",
|
||||
"naturesaura:infused_iron_block",
|
||||
"naturesaura:aura_detector",
|
||||
"naturesaura:spawn_lamp",
|
||||
"naturesaura:animal_container",
|
||||
"naturesaura:powder_placer",
|
||||
"naturesaura:weather_changer",
|
||||
"naturesaura:grated_chute",
|
||||
"naturesaura:crushing_catalyst",
|
||||
"naturesaura:conversion_catalyst",
|
||||
"naturesaura:ender_crate",
|
||||
"naturesaura:firework_generator",
|
||||
"naturesaura:tainted_gold_block",
|
||||
"naturesaura:placer",
|
||||
"naturesaura:blast_furnace_booster",
|
||||
"naturesaura:lower_limiter",
|
||||
"naturesaura:animal_generator",
|
||||
"naturesaura:nether_grass",
|
||||
"naturesaura:infused_iron_block",
|
||||
"naturesaura:snow_creator",
|
||||
"naturesaura:infused_stone",
|
||||
"naturesaura:field_creator",
|
||||
"naturesaura:nature_altar",
|
||||
"naturesaura:gold_nether_brick",
|
||||
"naturesaura:gold_brick"
|
||||
"naturesaura:aura_timer",
|
||||
"naturesaura:chunk_loader",
|
||||
"naturesaura:animal_spawner",
|
||||
"naturesaura:chorus_generator",
|
||||
"naturesaura:infused_brick_slab",
|
||||
"naturesaura:projectile_generator",
|
||||
"naturesaura:furnace_heater",
|
||||
"naturesaura:moss_generator",
|
||||
"naturesaura:rf_converter",
|
||||
"naturesaura:item_distributor",
|
||||
"naturesaura:time_changer",
|
||||
"naturesaura:conversion_catalyst",
|
||||
"naturesaura:hopper_upgrade",
|
||||
"naturesaura:pickup_stopper",
|
||||
"naturesaura:infused_brick",
|
||||
"naturesaura:generator_limit_remover",
|
||||
"naturesaura:infused_slab"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"type": "minecraft:block",
|
||||
"pools": [
|
||||
{
|
||||
"bonus_rolls": 0.0,
|
||||
"conditions": [
|
||||
{
|
||||
"condition": "minecraft:survives_explosion"
|
||||
}
|
||||
],
|
||||
"entries": [
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"name": "naturesaura:lower_limiter"
|
||||
}
|
||||
],
|
||||
"rolls": 1.0
|
||||
}
|
||||
]
|
||||
}
|
|
@ -60,9 +60,8 @@ public class BlockChunkLoader extends BlockContainerImpl implements IVisualizabl
|
|||
if (!ModConfig.instance.chunkLoader.get())
|
||||
return;
|
||||
var tile = levelIn.getBlockEntity(pos);
|
||||
if (tile instanceof BlockEntityChunkLoader) {
|
||||
var range = ((BlockEntityChunkLoader) tile).range();
|
||||
for (var i = Mth.ceil(range / 8F); i > 0; i--) {
|
||||
if (tile instanceof BlockEntityChunkLoader loader && loader.canUseRightNow(loader.getAuraUsed())) {
|
||||
for (var i = Mth.ceil(loader.range() / 8F); i > 0; i--) {
|
||||
NaturesAuraAPI.instance().spawnMagicParticle(
|
||||
pos.getX() + levelIn.random.nextFloat(), pos.getY() + levelIn.random.nextFloat(), pos.getZ() + levelIn.random.nextFloat(),
|
||||
0, 0, 0, 0xa12dff, 1F + levelIn.random.nextFloat(), 100, 0, false, true);
|
||||
|
|
|
@ -91,7 +91,7 @@ public class BlockEnderCrate extends BlockContainerImpl implements ITESRProvider
|
|||
public InteractionResult use(BlockState state, Level levelIn, BlockPos pos, Player player, InteractionHand handIn, BlockHitResult hit) {
|
||||
if (!levelIn.isClientSide) {
|
||||
var tile = levelIn.getBlockEntity(pos);
|
||||
if (tile instanceof BlockEntityEnderCrate crate && crate.canOpen()) {
|
||||
if (tile instanceof BlockEntityEnderCrate crate && crate.canOpen() && crate.canUseRightNow(2500)) {
|
||||
crate.drainAura(2500);
|
||||
NetworkHooks.openScreen((ServerPlayer) player, crate, pos);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
package de.ellpeck.naturesaura.blocks;
|
||||
|
||||
import de.ellpeck.naturesaura.blocks.tiles.BlockEntityLowerLimiter;
|
||||
import de.ellpeck.naturesaura.blocks.tiles.ModBlockEntities;
|
||||
import de.ellpeck.naturesaura.blocks.tiles.render.RenderLowerLimiter;
|
||||
import de.ellpeck.naturesaura.data.BlockStateGenerator;
|
||||
import de.ellpeck.naturesaura.reg.ICustomBlockState;
|
||||
import de.ellpeck.naturesaura.reg.ITESRProvider;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRenderers;
|
||||
import net.minecraft.world.level.block.SoundType;
|
||||
import net.minecraft.world.level.material.Material;
|
||||
|
||||
public class BlockLowerLimiter extends BlockContainerImpl implements ICustomBlockState, ITESRProvider<BlockEntityLowerLimiter> {
|
||||
|
||||
public BlockLowerLimiter() {
|
||||
super("lower_limiter", BlockEntityLowerLimiter.class, Properties.of(Material.STONE).strength(2F).sound(SoundType.STONE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateCustomBlockState(BlockStateGenerator generator) {
|
||||
generator.simpleBlock(this, generator.models().cubeBottomTop(this.getBaseName(),
|
||||
generator.modLoc("block/" + this.getBaseName()),
|
||||
generator.modLoc("block/" + this.getBaseName() + "_top"),
|
||||
generator.modLoc("block/" + this.getBaseName() + "_top")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerTESR() {
|
||||
BlockEntityRenderers.register(ModBlockEntities.LOWER_LIMITER, RenderLowerLimiter::new);
|
||||
}
|
||||
}
|
|
@ -10,7 +10,6 @@ import de.ellpeck.naturesaura.packet.PacketHandler;
|
|||
import de.ellpeck.naturesaura.packet.PacketParticles;
|
||||
import de.ellpeck.naturesaura.reg.ICustomBlockState;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.Mob;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
@ -45,15 +44,16 @@ public class BlockSpawnLamp extends BlockContainerImpl implements IVisualizable,
|
|||
|
||||
@SubscribeEvent
|
||||
public void onSpawn(LivingSpawnEvent.CheckSpawn event) {
|
||||
var amountToUse = 200;
|
||||
if (event.getSpawner() != null)
|
||||
return;
|
||||
var level = event.getLevel();
|
||||
var accessor = event.getLevel();
|
||||
var pos = new BlockPos(event.getX(), event.getY(), event.getZ());
|
||||
if (!(level instanceof Level))
|
||||
if (!(accessor instanceof Level level))
|
||||
return;
|
||||
var data = (LevelData) ILevelData.getLevelData((Level) level);
|
||||
var data = (LevelData) ILevelData.getLevelData(level);
|
||||
for (var lamp : data.spawnLamps) {
|
||||
if (lamp.isRemoved())
|
||||
if (lamp.isRemoved() || !lamp.canUseRightNow(amountToUse))
|
||||
continue;
|
||||
|
||||
var range = lamp.getRadius();
|
||||
|
@ -66,10 +66,10 @@ public class BlockSpawnLamp extends BlockContainerImpl implements IVisualizable,
|
|||
|
||||
var entity = (Mob) event.getEntity();
|
||||
if (entity.checkSpawnRules(level, event.getSpawnReason()) && entity.checkSpawnObstruction(level)) {
|
||||
var spot = IAuraChunk.getHighestSpot((Level) level, lampPos, 32, lampPos);
|
||||
IAuraChunk.getAuraChunk((Level) level, spot).drainAura(spot, 200);
|
||||
var spot = IAuraChunk.getHighestSpot(level, lampPos, 32, lampPos);
|
||||
IAuraChunk.getAuraChunk(level, spot).drainAura(spot, amountToUse);
|
||||
|
||||
PacketHandler.sendToAllAround((ServerLevel) level, lampPos, 32,
|
||||
PacketHandler.sendToAllAround(level, lampPos, 32,
|
||||
new PacketParticles(lampPos.getX(), lampPos.getY(), lampPos.getZ(), PacketParticles.Type.SPAWN_LAMP));
|
||||
}
|
||||
|
||||
|
|
|
@ -58,10 +58,9 @@ public class BlockSpring extends BlockContainerImpl implements ICustomBlockState
|
|||
|
||||
@Override
|
||||
public ItemStack pickupBlock(LevelAccessor levelIn, BlockPos pos, BlockState state) {
|
||||
var tile = levelIn.getBlockEntity(pos);
|
||||
if (tile instanceof BlockEntitySpring)
|
||||
((BlockEntitySpring) tile).consumeAura(2500);
|
||||
return new ItemStack(Items.WATER_BUCKET);
|
||||
if (levelIn.getBlockEntity(pos) instanceof BlockEntitySpring spring && spring.tryConsumeAura(2500))
|
||||
return new ItemStack(Items.WATER_BUCKET);
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -2,7 +2,7 @@ package de.ellpeck.naturesaura.blocks;
|
|||
|
||||
import net.minecraft.world.level.block.Block;
|
||||
|
||||
@SuppressWarnings("NonConstantFieldWithUpperCaseName")
|
||||
@SuppressWarnings("FieldNamingConvention")
|
||||
public final class ModBlocks {
|
||||
|
||||
public static Block ANCIENT_LOG;
|
||||
|
@ -74,4 +74,5 @@ public final class ModBlocks {
|
|||
public static Block CRIMSON_AURA_MUSHROOM;
|
||||
public static Block AURA_MUSHROOM;
|
||||
public static Block WEATHER_CHANGER;
|
||||
public static Block LOWER_LIMITER;
|
||||
}
|
||||
|
|
|
@ -51,6 +51,9 @@ public class BlockEntityAnimalSpawner extends BlockEntityImpl implements ITickab
|
|||
|
||||
if (this.currentRecipe != null) {
|
||||
var drain = Mth.ceil(this.currentRecipe.aura / (float) this.currentRecipe.time * 10F);
|
||||
if (!this.canUseRightNow(drain))
|
||||
return;
|
||||
|
||||
var spot = IAuraChunk.getHighestSpot(this.level, this.worldPosition, 35, this.worldPosition);
|
||||
IAuraChunk.getAuraChunk(this.level, spot).drainAura(spot, drain);
|
||||
|
||||
|
@ -164,4 +167,9 @@ public class BlockEntityAnimalSpawner extends BlockEntityImpl implements ITickab
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allowsLowerLimiter() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,10 @@ public class BlockEntityBlastFurnaceBooster extends BlockEntityImpl implements I
|
|||
if (this.level.isClientSide)
|
||||
return;
|
||||
|
||||
var toUse = 6500;
|
||||
if (!this.canUseRightNow(toUse))
|
||||
return;
|
||||
|
||||
var below = this.level.getBlockEntity(this.worldPosition.below());
|
||||
if (!(below instanceof BlastFurnaceBlockEntity tile))
|
||||
return;
|
||||
|
@ -60,7 +64,7 @@ public class BlockEntityBlastFurnaceBooster extends BlockEntityImpl implements I
|
|||
}
|
||||
|
||||
var pos = IAuraChunk.getHighestSpot(this.level, this.worldPosition, 30, this.worldPosition);
|
||||
IAuraChunk.getAuraChunk(this.level, pos).drainAura(pos, 6500);
|
||||
IAuraChunk.getAuraChunk(this.level, pos).drainAura(pos, toUse);
|
||||
|
||||
PacketHandler.sendToAllAround(this.level, this.worldPosition, 32,
|
||||
new PacketParticles(this.worldPosition.getX(), this.worldPosition.getY(), this.worldPosition.getZ(), PacketParticles.Type.BLAST_FURNACE_BOOSTER, 1));
|
||||
|
@ -129,4 +133,9 @@ public class BlockEntityBlastFurnaceBooster extends BlockEntityImpl implements I
|
|||
@Override
|
||||
public void dropInventory() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allowsLowerLimiter() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ public class BlockEntityChunkLoader extends BlockEntityImpl implements ITickable
|
|||
|
||||
private final List<ChunkPos> forcedChunks = new ArrayList<>();
|
||||
private boolean firstTick = true;
|
||||
private boolean canUseRightNow = true;
|
||||
|
||||
public BlockEntityChunkLoader(BlockPos pos, BlockState state) {
|
||||
super(ModBlockEntities.CHUNK_LOADER, pos, state);
|
||||
|
@ -42,6 +43,10 @@ public class BlockEntityChunkLoader extends BlockEntityImpl implements ITickable
|
|||
return this.redstonePower * 2;
|
||||
}
|
||||
|
||||
public int getAuraUsed() {
|
||||
return Mth.ceil(this.range() / 2F);
|
||||
}
|
||||
|
||||
private void loadChunks(boolean unload) {
|
||||
if (this.level.isClientSide || !ModConfig.instance.chunkLoader.get())
|
||||
return;
|
||||
|
@ -50,7 +55,7 @@ public class BlockEntityChunkLoader extends BlockEntityImpl implements ITickable
|
|||
List<ChunkPos> shouldBeForced = new ArrayList<>();
|
||||
if (!unload) {
|
||||
var range = this.range();
|
||||
if (range > 0) {
|
||||
if (range > 0 && this.canUseRightNow) {
|
||||
for (var x = this.worldPosition.getX() - range >> 4; x <= this.worldPosition.getX() + range >> 4; x++) {
|
||||
for (var z = this.worldPosition.getZ() - range >> 4; z <= this.worldPosition.getZ() + range >> 4; z++) {
|
||||
var pos = new ChunkPos(x, z);
|
||||
|
@ -86,10 +91,16 @@ public class BlockEntityChunkLoader extends BlockEntityImpl implements ITickable
|
|||
this.firstTick = false;
|
||||
}
|
||||
|
||||
var toUse = this.getAuraUsed();
|
||||
var canUse = this.canUseRightNow(toUse);
|
||||
if (this.canUseRightNow != canUse) {
|
||||
this.canUseRightNow = canUse;
|
||||
this.loadChunks(false);
|
||||
}
|
||||
|
||||
if (this.level.getGameTime() % 20 != 0)
|
||||
return;
|
||||
var toUse = Mth.ceil(this.range() / 2F);
|
||||
if (toUse > 0) {
|
||||
if (toUse > 0 && this.canUseRightNow) {
|
||||
var spot = IAuraChunk.getHighestSpot(this.level, this.worldPosition, 35, this.worldPosition);
|
||||
IAuraChunk.getAuraChunk(this.level, spot).drainAura(spot, toUse);
|
||||
}
|
||||
|
@ -112,4 +123,9 @@ public class BlockEntityChunkLoader extends BlockEntityImpl implements ITickable
|
|||
Arrays.stream(compound.getLongArray("forced_chunks")).mapToObj(ChunkPos::new).forEach(this.forcedChunks::add);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allowsLowerLimiter() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,6 +44,8 @@ public class BlockEntityEnderCrate extends BlockEntityImpl implements MenuProvid
|
|||
@Nonnull
|
||||
@Override
|
||||
public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate) {
|
||||
if (!BlockEntityEnderCrate.this.canUseRightNow(20))
|
||||
return stack;
|
||||
var remain = this.getStorage().insertItem(slot, stack, simulate);
|
||||
if (!simulate)
|
||||
BlockEntityEnderCrate.this.drainAura((stack.getCount() - remain.getCount()) * 20);
|
||||
|
@ -53,6 +55,8 @@ public class BlockEntityEnderCrate extends BlockEntityImpl implements MenuProvid
|
|||
@Nonnull
|
||||
@Override
|
||||
public ItemStack extractItem(int slot, int amount, boolean simulate) {
|
||||
if (!BlockEntityEnderCrate.this.canUseRightNow(20))
|
||||
return ItemStack.EMPTY;
|
||||
var extracted = this.getStorage().extractItem(slot, amount, simulate);
|
||||
if (!simulate)
|
||||
BlockEntityEnderCrate.this.drainAura(extracted.getCount() * 20);
|
||||
|
@ -147,4 +151,9 @@ public class BlockEntityEnderCrate extends BlockEntityImpl implements MenuProvid
|
|||
public AbstractContainerMenu createMenu(int window, Inventory inv, Player player) {
|
||||
return new ContainerEnderCrate(ModContainers.ENDER_CRATE, window, player, this.getItemHandler());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allowsLowerLimiter() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ public class BlockEntityFieldCreator extends BlockEntityImpl implements ITickabl
|
|||
if (!this.isMain)
|
||||
return;
|
||||
|
||||
if (this.redstonePower <= 0 && creator.redstonePower <= 0) {
|
||||
if (this.redstonePower <= 0 && creator.redstonePower <= 0 || !this.canUseRightNow(20)) {
|
||||
this.chargeTimer = 0;
|
||||
if (this.isCharged) {
|
||||
this.isCharged = false;
|
||||
|
@ -106,7 +106,6 @@ public class BlockEntityFieldCreator extends BlockEntityImpl implements ITickabl
|
|||
continue;
|
||||
|
||||
var state = this.level.getBlockState(pos);
|
||||
var block = state.getBlock();
|
||||
if (!state.isAir() && state.getDestroySpeed(this.level, pos) >= 0F) {
|
||||
var fake = FakePlayerFactory.getMinecraft((ServerLevel) this.level);
|
||||
if (!MinecraftForge.EVENT_BUS.post(new BlockEvent.BreakEvent(this.level, pos, state, fake))) {
|
||||
|
@ -204,4 +203,9 @@ public class BlockEntityFieldCreator extends BlockEntityImpl implements ITickabl
|
|||
this.chargeTimer = compound.getInt("timer");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allowsLowerLimiter() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,25 +64,28 @@ public class BlockEntityFurnaceHeater extends BlockEntityImpl implements ITickab
|
|||
if (burnTime <= 0)
|
||||
this.level.setBlockAndUpdate(tilePos, this.level.getBlockState(tilePos).setValue(AbstractFurnaceBlock.LIT, true));
|
||||
|
||||
data.set(0, 200);
|
||||
// we leave some wiggle room for the furnace to do its own checks + the blast furnace booster
|
||||
data.set(2, Math.min(data.get(3) - 2, data.get(2) + 5));
|
||||
var toDrain = Mth.ceil((200 - burnTime) * 16.6F);
|
||||
if (this.canUseRightNow(toDrain)) {
|
||||
data.set(0, 200);
|
||||
// we leave some wiggle room for the furnace to do its own checks + the blast furnace booster
|
||||
data.set(2, Math.min(data.get(3) - 2, data.get(2) + 5));
|
||||
|
||||
var spot = IAuraChunk.getHighestSpot(this.level, this.worldPosition, 20, this.worldPosition);
|
||||
var chunk = IAuraChunk.getAuraChunk(this.level, spot);
|
||||
chunk.drainAura(spot, Mth.ceil((200 - burnTime) * 16.6F));
|
||||
did = true;
|
||||
var spot = IAuraChunk.getHighestSpot(this.level, this.worldPosition, 20, this.worldPosition);
|
||||
var chunk = IAuraChunk.getAuraChunk(this.level, spot);
|
||||
chunk.drainAura(spot, toDrain);
|
||||
did = true;
|
||||
|
||||
if (this.level.getGameTime() % 15 == 0) {
|
||||
PacketHandler.sendToAllAround(this.level, this.worldPosition, 32, new PacketParticleStream(
|
||||
this.worldPosition.getX() + (float) this.level.random.nextGaussian() * 5F,
|
||||
this.worldPosition.getY() + 1 + this.level.random.nextFloat() * 5F,
|
||||
this.worldPosition.getZ() + (float) this.level.random.nextGaussian() * 5F,
|
||||
tilePos.getX() + this.level.random.nextFloat(),
|
||||
tilePos.getY() + this.level.random.nextFloat(),
|
||||
tilePos.getZ() + this.level.random.nextFloat(),
|
||||
this.level.random.nextFloat() * 0.07F + 0.07F, IAuraType.forLevel(this.level).getColor(), this.level.random.nextFloat() + 0.5F
|
||||
));
|
||||
if (this.level.getGameTime() % 15 == 0) {
|
||||
PacketHandler.sendToAllAround(this.level, this.worldPosition, 32, new PacketParticleStream(
|
||||
this.worldPosition.getX() + (float) this.level.random.nextGaussian() * 5F,
|
||||
this.worldPosition.getY() + 1 + this.level.random.nextFloat() * 5F,
|
||||
this.worldPosition.getZ() + (float) this.level.random.nextGaussian() * 5F,
|
||||
tilePos.getX() + this.level.random.nextFloat(),
|
||||
tilePos.getY() + this.level.random.nextFloat(),
|
||||
tilePos.getZ() + this.level.random.nextFloat(),
|
||||
this.level.random.nextFloat() * 0.07F + 0.07F, IAuraType.forLevel(this.level).getColor(), this.level.random.nextFloat() + 0.5F
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -124,4 +127,9 @@ public class BlockEntityFurnaceHeater extends BlockEntityImpl implements ITickab
|
|||
if (type == SaveType.SYNC)
|
||||
this.isActive = compound.getBoolean("active");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allowsLowerLimiter() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,6 +44,10 @@ public class BlockEntityHopperUpgrade extends BlockEntityImpl implements ITickab
|
|||
if (items.isEmpty())
|
||||
return;
|
||||
|
||||
var drainPerItem = 500;
|
||||
if (!this.canUseRightNow(drainPerItem * items.size()))
|
||||
return;
|
||||
|
||||
for (var item : items) {
|
||||
if (!item.isAlive() || item.hasPickUpDelay())
|
||||
continue;
|
||||
|
@ -65,7 +69,7 @@ public class BlockEntityHopperUpgrade extends BlockEntityImpl implements ITickab
|
|||
item.kill();
|
||||
|
||||
var spot = IAuraChunk.getHighestSpot(this.level, this.worldPosition, 25, this.worldPosition);
|
||||
IAuraChunk.getAuraChunk(this.level, spot).drainAura(spot, 500);
|
||||
IAuraChunk.getAuraChunk(this.level, spot).drainAura(spot, drainPerItem);
|
||||
|
||||
PacketHandler.sendToAllAround(this.level, this.worldPosition, 32,
|
||||
new PacketParticles((float) item.getX(), (float) item.getY(), (float) item.getZ(), PacketParticles.Type.HOPPER_UPGRADE));
|
||||
|
@ -73,4 +77,9 @@ public class BlockEntityHopperUpgrade extends BlockEntityImpl implements ITickab
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allowsLowerLimiter() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -165,6 +165,20 @@ public class BlockEntityImpl extends BlockEntity {
|
|||
}
|
||||
}
|
||||
|
||||
public boolean canUseRightNow(int toUse) {
|
||||
if (this.allowsLowerLimiter()) {
|
||||
for (var dir : Direction.values()) {
|
||||
var offset = this.worldPosition.relative(dir);
|
||||
if (this.level.getBlockState(offset).getBlock() == ModBlocks.LOWER_LIMITER) {
|
||||
var aura = IAuraChunk.getAuraInArea(this.level, this.worldPosition, 35);
|
||||
return aura - toUse > 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean canGenerateRightNow(int toAdd) {
|
||||
if (this.wantsLimitRemover()) {
|
||||
var below = this.level.getBlockState(this.worldPosition.below());
|
||||
|
@ -179,6 +193,10 @@ public class BlockEntityImpl extends BlockEntity {
|
|||
return false;
|
||||
}
|
||||
|
||||
public boolean allowsLowerLimiter() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void generateAura(int amount) {
|
||||
while (amount > 0) {
|
||||
var spot = IAuraChunk.getLowestSpot(this.level, this.worldPosition, 35, this.worldPosition);
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
package de.ellpeck.naturesaura.blocks.tiles;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
public class BlockEntityLowerLimiter extends BlockEntityImpl {
|
||||
|
||||
public BlockEntityLowerLimiter(BlockPos pos, BlockState state) {
|
||||
super(ModBlockEntities.LOWER_LIMITER, pos, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public AABB getRenderBoundingBox() {
|
||||
return new AABB(this.worldPosition, this.worldPosition.offset(1, 2, 1));
|
||||
}
|
||||
}
|
|
@ -44,6 +44,10 @@ public class BlockEntityPlacer extends BlockEntityImpl implements ITickableBlock
|
|||
if (frames.isEmpty())
|
||||
return;
|
||||
|
||||
var toDrain = 1000;
|
||||
if (!this.canUseRightNow(toDrain))
|
||||
return;
|
||||
|
||||
List<BlockPos> validPositions = new ArrayList<>();
|
||||
var range = 5;
|
||||
for (var x = -range; x <= range; x++)
|
||||
|
@ -73,7 +77,7 @@ public class BlockEntityPlacer extends BlockEntityImpl implements ITickableBlock
|
|||
|
||||
handler.extractItem(i, 1, false);
|
||||
var spot = IAuraChunk.getHighestSpot(this.level, this.worldPosition, 10, this.worldPosition);
|
||||
IAuraChunk.getAuraChunk(this.level, spot).drainAura(spot, 1000);
|
||||
IAuraChunk.getAuraChunk(this.level, spot).drainAura(spot, toDrain);
|
||||
|
||||
PacketHandler.sendToAllAround(this.level, this.worldPosition, 32, new PacketParticles(pos.getX(), pos.getY(), pos.getZ(), PacketParticles.Type.PLACER_PLACING));
|
||||
|
||||
|
@ -82,6 +86,11 @@ public class BlockEntityPlacer extends BlockEntityImpl implements ITickableBlock
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allowsLowerLimiter() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean framesContain(List<ItemFrame> frames, BlockState state) {
|
||||
var stack = new ItemStack(state.getBlock());
|
||||
if (stack.isEmpty())
|
||||
|
|
|
@ -39,6 +39,10 @@ public class BlockEntitySnowCreator extends BlockEntityImpl implements ITickable
|
|||
if (range <= 0)
|
||||
return;
|
||||
|
||||
var toDrain = 300;
|
||||
if (!this.canUseRightNow(toDrain))
|
||||
return;
|
||||
|
||||
if (!this.level.isClientSide) {
|
||||
if (this.level.getGameTime() % 10 != 0)
|
||||
return;
|
||||
|
@ -67,7 +71,7 @@ public class BlockEntitySnowCreator extends BlockEntityImpl implements ITickable
|
|||
}
|
||||
|
||||
var auraPos = IAuraChunk.getHighestSpot(this.level, this.worldPosition, 30, this.worldPosition);
|
||||
IAuraChunk.getAuraChunk(this.level, auraPos).drainAura(auraPos, 300);
|
||||
IAuraChunk.getAuraChunk(this.level, auraPos).drainAura(auraPos, toDrain);
|
||||
|
||||
PacketHandler.sendToAllAround(this.level, this.worldPosition, 32,
|
||||
new PacketParticles(this.worldPosition.getX(), this.worldPosition.getY(), this.worldPosition.getZ(), PacketParticles.Type.SNOW_CREATOR));
|
||||
|
@ -104,4 +108,9 @@ public class BlockEntitySnowCreator extends BlockEntityImpl implements ITickable
|
|||
if (type == SaveType.TILE)
|
||||
this.snowmanCount = compound.getInt("snowman_count");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allowsLowerLimiter() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,4 +39,9 @@ public class BlockEntitySpawnLamp extends BlockEntityImpl {
|
|||
if (!this.level.isClientSide)
|
||||
this.sendToClients();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allowsLowerLimiter() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,10 +62,9 @@ public class BlockEntitySpring extends BlockEntityImpl implements ITickableBlock
|
|||
var upState = this.level.getBlockState(up);
|
||||
if (upState.hasProperty(BlockStateProperties.LEVEL_CAULDRON)) {
|
||||
int level = upState.getValue(BlockStateProperties.LEVEL_CAULDRON);
|
||||
if (level < 3) {
|
||||
if (level < 3 && this.tryConsumeAura(2500)) {
|
||||
this.level.setBlockAndUpdate(up, upState.setValue(BlockStateProperties.LEVEL_CAULDRON, level + 1));
|
||||
this.level.playSound(null, up, SoundEvents.BUCKET_FILL, SoundSource.BLOCKS, 1, 1);
|
||||
this.consumeAura(2500);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -77,10 +76,9 @@ public class BlockEntitySpring extends BlockEntityImpl implements ITickableBlock
|
|||
for (var z = -spongeRadius; z <= spongeRadius; z++) {
|
||||
var pos = this.worldPosition.offset(x, y, z);
|
||||
var state = this.level.getBlockState(pos);
|
||||
if (state.getBlock() == Blocks.SPONGE) {
|
||||
if (state.getBlock() == Blocks.SPONGE && this.tryConsumeAura(2500)) {
|
||||
this.level.setBlock(pos, Blocks.WET_SPONGE.defaultBlockState(), 2);
|
||||
this.level.levelEvent(2001, pos, Block.getId(Blocks.WATER.defaultBlockState()));
|
||||
this.consumeAura(2500);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -90,20 +88,18 @@ public class BlockEntitySpring extends BlockEntityImpl implements ITickableBlock
|
|||
// generate obsidian
|
||||
for (var dir : Direction.Plane.HORIZONTAL) {
|
||||
var side = this.worldPosition.relative(dir);
|
||||
if (this.isLava(side, true)) {
|
||||
if (this.isLava(side, true) && this.tryConsumeAura(1500)) {
|
||||
this.level.setBlockAndUpdate(side, ForgeEventFactory.fireFluidPlaceBlockEvent(this.level, side, side, Blocks.OBSIDIAN.defaultBlockState()));
|
||||
this.level.levelEvent(1501, side, 0);
|
||||
this.consumeAura(1500);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// generate stone
|
||||
var twoUp = this.worldPosition.above(2);
|
||||
if (this.isLava(twoUp, false) && (this.level.getBlockState(up).isAir() || this.isLava(up, false))) {
|
||||
if (this.isLava(twoUp, false) && (this.level.getBlockState(up).isAir() || this.isLava(up, false)) && this.tryConsumeAura(150)) {
|
||||
this.level.setBlockAndUpdate(up, ForgeEventFactory.fireFluidPlaceBlockEvent(this.level, up, twoUp, Blocks.STONE.defaultBlockState()));
|
||||
this.level.levelEvent(1501, up, 0);
|
||||
this.consumeAura(150);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -111,10 +107,9 @@ public class BlockEntitySpring extends BlockEntityImpl implements ITickableBlock
|
|||
for (var dir : Direction.Plane.HORIZONTAL) {
|
||||
var twoSide = this.worldPosition.relative(dir, 2);
|
||||
var side = this.worldPosition.relative(dir);
|
||||
if (this.isLava(twoSide, false) && (this.level.getBlockState(side).isAir() || this.isLava(side, false))) {
|
||||
if (this.isLava(twoSide, false) && (this.level.getBlockState(side).isAir() || this.isLava(side, false)) && this.tryConsumeAura(100)) {
|
||||
this.level.setBlockAndUpdate(side, ForgeEventFactory.fireFluidPlaceBlockEvent(this.level, side, twoSide, Blocks.COBBLESTONE.defaultBlockState()));
|
||||
this.level.levelEvent(1501, side, 0);
|
||||
this.consumeAura(100);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -127,11 +122,17 @@ public class BlockEntitySpring extends BlockEntityImpl implements ITickableBlock
|
|||
return LazyOptional.empty();
|
||||
}
|
||||
|
||||
public void consumeAura(int amount) {
|
||||
while (amount > 0) {
|
||||
var pos = IAuraChunk.getHighestSpot(this.level, this.worldPosition, 35, this.worldPosition);
|
||||
amount -= IAuraChunk.getAuraChunk(this.level, pos).drainAura(pos, amount);
|
||||
}
|
||||
@Override
|
||||
public boolean allowsLowerLimiter() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean tryConsumeAura(int amount) {
|
||||
if (!this.canUseRightNow(amount))
|
||||
return false;
|
||||
var pos = IAuraChunk.getHighestSpot(this.level, this.worldPosition, 35, this.worldPosition);
|
||||
IAuraChunk.getAuraChunk(this.level, pos).drainAura(pos, amount);
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isLava(BlockPos offset, boolean source) {
|
||||
|
@ -169,8 +170,11 @@ public class BlockEntitySpring extends BlockEntityImpl implements ITickableBlock
|
|||
@Override
|
||||
public FluidStack drain(int maxDrain, IFluidHandler.FluidAction action) {
|
||||
var drain = Math.min(maxDrain, 1000);
|
||||
var auraUsed = Mth.ceil(drain / 2F);
|
||||
if (!BlockEntitySpring.this.canUseRightNow(auraUsed))
|
||||
return FluidStack.EMPTY;
|
||||
if (action.execute())
|
||||
BlockEntitySpring.this.consumeAura(Mth.ceil(drain / 2F));
|
||||
BlockEntitySpring.this.tryConsumeAura(auraUsed);
|
||||
return new FluidStack(Fluids.WATER, drain);
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ public class BlockEntityTimeChanger extends BlockEntityImpl implements ITickable
|
|||
if (this.goalTime > 0) {
|
||||
var current = this.level.getDayTime();
|
||||
var toAdd = Math.min(75, this.goalTime - current);
|
||||
if (toAdd <= 0) {
|
||||
if (toAdd <= 0 || !this.canUseRightNow((int) toAdd * 20)) {
|
||||
this.goalTime = 0;
|
||||
this.sendToClients();
|
||||
return;
|
||||
|
@ -118,4 +118,9 @@ public class BlockEntityTimeChanger extends BlockEntityImpl implements ITickable
|
|||
if (type != SaveType.BLOCK)
|
||||
this.goalTime = compound.getLong("goal");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allowsLowerLimiter() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,9 +51,16 @@ public class BlockEntityWeatherChanger extends BlockEntityImpl implements ITicka
|
|||
}
|
||||
|
||||
if (this.processTime > 0) {
|
||||
var auraToUse = 30000 * Mth.ceil(this.itemAmount * 0.75F);
|
||||
if (!this.canUseRightNow(auraToUse)) {
|
||||
this.processTime = 0;
|
||||
this.sendToClients();
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.processTime % 20 == 0) {
|
||||
var spot = IAuraChunk.getHighestSpot(this.level, this.worldPosition, 35, this.worldPosition);
|
||||
IAuraChunk.getAuraChunk(this.level, spot).drainAura(spot, 30000 * Mth.ceil(this.itemAmount * 0.75F));
|
||||
IAuraChunk.getAuraChunk(this.level, spot).drainAura(spot, auraToUse);
|
||||
}
|
||||
|
||||
this.processTime--;
|
||||
|
@ -101,6 +108,11 @@ public class BlockEntityWeatherChanger extends BlockEntityImpl implements ITicka
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allowsLowerLimiter() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private Pair<WeatherType, Integer> getNextWeatherType() {
|
||||
var area = new AABB(this.worldPosition).inflate(2);
|
||||
var items = this.level.getEntitiesOfClass(ItemEntity.class, area, Entity::isAlive);
|
||||
|
|
|
@ -2,7 +2,7 @@ package de.ellpeck.naturesaura.blocks.tiles;
|
|||
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||
|
||||
@SuppressWarnings("NonConstantFieldWithUpperCaseName")
|
||||
@SuppressWarnings("FieldNamingConvention")
|
||||
public final class ModBlockEntities {
|
||||
|
||||
public static BlockEntityType<BlockEntityAncientLeaves> ANCIENT_LEAVES;
|
||||
|
@ -43,4 +43,5 @@ public final class ModBlockEntities {
|
|||
public static BlockEntityType<BlockEntitySlimeSplitGenerator> SLIME_SPLIT_GENERATOR;
|
||||
public static BlockEntityType<BlockEntitySpring> SPRING;
|
||||
public static BlockEntityType<BlockEntityWeatherChanger> WEATHER_CHANGER;
|
||||
public static BlockEntityType<BlockEntityLowerLimiter> LOWER_LIMITER;
|
||||
}
|
||||
|
|
|
@ -34,23 +34,23 @@ public class RenderGeneratorLimitRemover implements BlockEntityRenderer<BlockEnt
|
|||
public void render(BlockEntityGeneratorLimitRemover te, float v, PoseStack matrixStack, MultiBufferSource iRenderTypeBuffer, int combinedLightIn, int combinedOverlayIn) {
|
||||
var above = te.getLevel().getBlockEntity(te.getBlockPos().above());
|
||||
if (above instanceof BlockEntityImpl && ((BlockEntityImpl) above).wantsLimitRemover()) {
|
||||
this.renderGlint(matrixStack, iRenderTypeBuffer, 1, combinedOverlayIn);
|
||||
this.renderGlint(matrixStack, iRenderTypeBuffer, 0, combinedOverlayIn);
|
||||
RenderGeneratorLimitRemover.renderGlint(matrixStack, iRenderTypeBuffer, this.model, 0, 1, 0, combinedOverlayIn, RenderGeneratorLimitRemover.RES, 1);
|
||||
RenderGeneratorLimitRemover.renderGlint(matrixStack, iRenderTypeBuffer, this.model, 0, 0, 0, combinedOverlayIn, RenderGeneratorLimitRemover.RES, 1);
|
||||
}
|
||||
}
|
||||
|
||||
private void renderGlint(PoseStack stack, MultiBufferSource buffer, double yOff, int combinedOverlayIn) {
|
||||
public static void renderGlint(PoseStack stack, MultiBufferSource buffer, ModelLimitRemoverGlint model, int xOff, int yOff, int zOff, int combinedOverlayIn, ResourceLocation texture, float maxAlpha) {
|
||||
stack.pushPose();
|
||||
var brightness = 15 << 20 | 15 << 4;
|
||||
var alpha = ((float) Math.sin(System.currentTimeMillis() / 800D) + 1F) / 2F;
|
||||
stack.translate(-0.001F, yOff + 1 + 0.001F, 1 + 0.001F);
|
||||
stack.translate(-0.002F + xOff, 1 + 0.002F + yOff, 1 + 0.002F + zOff);
|
||||
stack.mulPose(Vector3f.XP.rotationDegrees(180F));
|
||||
stack.scale(1.002F, 1.002F, 1.002F);
|
||||
this.model.renderToBuffer(stack, buffer.getBuffer(this.model.renderType(RenderGeneratorLimitRemover.RES)), brightness, combinedOverlayIn, 1, 1, 1, alpha);
|
||||
stack.scale(1.004F, 1.004F, 1.004F);
|
||||
model.renderToBuffer(stack, buffer.getBuffer(model.renderType(texture)), brightness, combinedOverlayIn, 1, 1, 1, alpha * maxAlpha);
|
||||
stack.popPose();
|
||||
}
|
||||
|
||||
private static class ModelLimitRemoverGlint extends Model {
|
||||
public static class ModelLimitRemoverGlint extends Model {
|
||||
|
||||
private final ModelPart model;
|
||||
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
package de.ellpeck.naturesaura.blocks.tiles.render;
|
||||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import de.ellpeck.naturesaura.NaturesAura;
|
||||
import de.ellpeck.naturesaura.blocks.tiles.BlockEntityImpl;
|
||||
import de.ellpeck.naturesaura.blocks.tiles.BlockEntityLowerLimiter;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
|
||||
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
import static de.ellpeck.naturesaura.blocks.tiles.render.RenderGeneratorLimitRemover.ModelLimitRemoverGlint;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class RenderLowerLimiter implements BlockEntityRenderer<BlockEntityLowerLimiter> {
|
||||
|
||||
private static final ResourceLocation RES = new ResourceLocation(NaturesAura.MOD_ID, "textures/models/lower_limiter_glint.png");
|
||||
private final ModelLimitRemoverGlint model = new ModelLimitRemoverGlint();
|
||||
|
||||
public RenderLowerLimiter(BlockEntityRendererProvider.Context context) {}
|
||||
|
||||
@Override
|
||||
public void render(BlockEntityLowerLimiter te, float v, PoseStack matrixStack, MultiBufferSource iRenderTypeBuffer, int combinedLightIn, int combinedOverlayIn) {
|
||||
for (var dir : Direction.values()) {
|
||||
var offset = te.getBlockPos().relative(dir);
|
||||
if (te.getLevel().getBlockEntity(offset) instanceof BlockEntityImpl impl && impl.allowsLowerLimiter()) {
|
||||
var alpha = te.getLevel().getBlockState(offset).isCollisionShapeFullBlock(te.getLevel(), offset) ? 1 : 0.25F;
|
||||
RenderGeneratorLimitRemover.renderGlint(matrixStack, iRenderTypeBuffer, this.model, dir.getStepX(), dir.getStepY(), dir.getStepZ(), combinedOverlayIn, RenderLowerLimiter.RES, alpha);
|
||||
RenderGeneratorLimitRemover.renderGlint(matrixStack, iRenderTypeBuffer, this.model, 0, 0, 0, combinedOverlayIn, RenderLowerLimiter.RES, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -17,7 +17,7 @@ public class SpreadEffect implements IDrainSpotEffect {
|
|||
|
||||
@Override
|
||||
public void update(Level level, LevelChunk chunk, IAuraChunk auraChunk, BlockPos pos, Integer spot) {
|
||||
if (Math.abs(spot) < 500000 || Math.abs(IAuraChunk.getAuraInArea(level, pos, 25)) < 2000000)
|
||||
if (Math.abs(spot) < 500000 || Math.abs(IAuraChunk.getAuraInArea(level, pos, 25) - IAuraChunk.DEFAULT_AURA) < 1000000)
|
||||
return;
|
||||
var drain = spot > 0;
|
||||
var toMove = Mth.ceil(Math.abs(spot) * 0.72F);
|
||||
|
|
|
@ -7,6 +7,7 @@ import de.ellpeck.naturesaura.data.ItemModelGenerator;
|
|||
import de.ellpeck.naturesaura.reg.IColorProvidingItem;
|
||||
import de.ellpeck.naturesaura.reg.ICustomItemModel;
|
||||
import net.minecraft.client.color.item.ItemColor;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.core.dispenser.DefaultDispenseItemBehavior;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
@ -42,33 +43,15 @@ public class ItemAuraBottle extends ItemImpl implements IColorProvidingItem, ICu
|
|||
|
||||
var dispense = stack.split(1);
|
||||
if (offsetState.isAir()) {
|
||||
if (IAuraChunk.getAuraInArea(level, offset, 30) >= 100000) {
|
||||
dispense = ItemAuraBottle.setType(new ItemStack(ItemAuraBottle.this), IAuraType.forLevel(level));
|
||||
|
||||
var spot = IAuraChunk.getHighestSpot(level, offset, 30, offset);
|
||||
IAuraChunk.getAuraChunk(level, spot).drainAura(spot, 20000);
|
||||
}
|
||||
var bottle = ItemAuraBottle.create(level, offset);
|
||||
if (!bottle.isEmpty())
|
||||
dispense = bottle;
|
||||
}
|
||||
|
||||
DefaultDispenseItemBehavior.spawnItem(level, dispense, 6, facing, DispenserBlock.getDispensePosition(source));
|
||||
return stack;
|
||||
});
|
||||
}
|
||||
|
||||
public static IAuraType getType(ItemStack stack) {
|
||||
if (!stack.hasTag())
|
||||
return NaturesAuraAPI.TYPE_OTHER;
|
||||
var type = stack.getTag().getString("stored_type");
|
||||
if (type.isEmpty())
|
||||
return NaturesAuraAPI.TYPE_OTHER;
|
||||
return NaturesAuraAPI.AURA_TYPES.get(new ResourceLocation(type));
|
||||
}
|
||||
|
||||
public static ItemStack setType(ItemStack stack, IAuraType type) {
|
||||
stack.getOrCreateTag().putString("stored_type", type.getName().toString());
|
||||
return stack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillItemCategory(CreativeModeTab tab, NonNullList<ItemStack> items) {
|
||||
if (this.allowedIn(tab)) {
|
||||
|
@ -98,7 +81,34 @@ public class ItemAuraBottle extends ItemImpl implements IColorProvidingItem, ICu
|
|||
.texture("layer1", "item/" + this.getBaseName() + "_overlay");
|
||||
}
|
||||
|
||||
private class EventHandler {
|
||||
public static IAuraType getType(ItemStack stack) {
|
||||
if (!stack.hasTag())
|
||||
return NaturesAuraAPI.TYPE_OTHER;
|
||||
var type = stack.getTag().getString("stored_type");
|
||||
if (type.isEmpty())
|
||||
return NaturesAuraAPI.TYPE_OTHER;
|
||||
return NaturesAuraAPI.AURA_TYPES.get(new ResourceLocation(type));
|
||||
}
|
||||
|
||||
public static ItemStack setType(ItemStack stack, IAuraType type) {
|
||||
stack.getOrCreateTag().putString("stored_type", type.getName().toString());
|
||||
return stack;
|
||||
}
|
||||
|
||||
private static ItemStack create(Level level, BlockPos pos) {
|
||||
var aura = IAuraChunk.getAuraInArea(level, pos, 30);
|
||||
if (aura <= -100000) {
|
||||
return new ItemStack(ModItems.VACUUM_BOTTLE);
|
||||
} else if (aura >= 100000) {
|
||||
var spot = IAuraChunk.getHighestSpot(level, pos, 30, pos);
|
||||
IAuraChunk.getAuraChunk(level, spot).drainAura(spot, 20000);
|
||||
return ItemAuraBottle.setType(new ItemStack(ModItems.AURA_BOTTLE), IAuraType.forLevel(level));
|
||||
} else {
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
private static class EventHandler {
|
||||
|
||||
@SubscribeEvent
|
||||
public void onRightClick(PlayerInteractEvent.RightClickItem event) {
|
||||
|
@ -109,23 +119,19 @@ public class ItemAuraBottle extends ItemImpl implements IColorProvidingItem, ICu
|
|||
HitResult ray = Item.getPlayerPOVHitResult(player.level, player, ClipContext.Fluid.NONE);
|
||||
if (ray.getType() == HitResult.Type.BLOCK)
|
||||
return;
|
||||
var pos = player.blockPosition();
|
||||
if (IAuraChunk.getAuraInArea(player.level, pos, 30) < 100000)
|
||||
var bottle = ItemAuraBottle.create(player.level, player.blockPosition());
|
||||
if (bottle.isEmpty())
|
||||
return;
|
||||
|
||||
if (!player.level.isClientSide) {
|
||||
held.shrink(1);
|
||||
|
||||
var stack = ItemAuraBottle.setType(new ItemStack(ItemAuraBottle.this), IAuraType.forLevel(player.level));
|
||||
if (!player.addItem(stack))
|
||||
player.level.addFreshEntity(new ItemEntity(player.level, player.getX(), player.getY(), player.getZ(), stack));
|
||||
|
||||
var spot = IAuraChunk.getHighestSpot(player.level, pos, 30, pos);
|
||||
IAuraChunk.getAuraChunk(player.level, spot).drainAura(spot, 20000);
|
||||
if (!player.addItem(bottle))
|
||||
player.level.addFreshEntity(new ItemEntity(player.level, player.getX(), player.getY(), player.getZ(), bottle));
|
||||
|
||||
player.level.playSound(null, player.getX(), player.getY(), player.getZ(),
|
||||
SoundEvents.BOTTLE_FILL_DRAGONBREATH, SoundSource.PLAYERS, 1F, 1F);
|
||||
}
|
||||
|
||||
player.swing(event.getHand());
|
||||
}
|
||||
|
||||
|
|
|
@ -64,4 +64,5 @@ public final class ModItems {
|
|||
public static Item BREAK_PREVENTION;
|
||||
public static Item PET_REVIVER;
|
||||
public static Item NETHERITE_FINDER;
|
||||
public static Item VACUUM_BOTTLE;
|
||||
}
|
||||
|
|
|
@ -133,7 +133,9 @@ public final class ModRegistry {
|
|||
new BlockSpring(),
|
||||
new BlockWeatherChanger(),
|
||||
new BlockRFConverter(),
|
||||
new BlockChunkLoader());
|
||||
new BlockChunkLoader(),
|
||||
new BlockLowerLimiter()
|
||||
);
|
||||
Helper.populateObjectHolders(ModBlocks.class, event.getForgeRegistry());
|
||||
});
|
||||
|
||||
|
@ -206,7 +208,8 @@ public final class ModRegistry {
|
|||
new ItemStructureFinder("outpost_finder", BuiltinStructures.PILLAGER_OUTPOST, 0xab9f98, 2048),
|
||||
new ItemBreakPrevention(),
|
||||
new ItemPetReviver(),
|
||||
new ItemNetheriteFinder()
|
||||
new ItemNetheriteFinder(),
|
||||
new ItemImpl("vacuum_bottle")
|
||||
);
|
||||
Helper.populateObjectHolders(ModItems.class, event.getForgeRegistry());
|
||||
});
|
||||
|
|
|
@ -78,6 +78,7 @@
|
|||
"block.naturesaura.slime_split_generator": "Offshoot Observer",
|
||||
"block.naturesaura.spring": "Everlasting Spring",
|
||||
"block.naturesaura.weather_changer": "Cloudshifter",
|
||||
"block.naturesaura.lower_limiter": "Aura Imbalance Ward",
|
||||
"item.naturesaura.eye": "Environmental Eye",
|
||||
"item.naturesaura.eye_improved": "Environmental Ocular",
|
||||
"item.naturesaura.gold_fiber": "Brilliant Fiber",
|
||||
|
@ -94,6 +95,7 @@
|
|||
"item.naturesaura.book.name": "Book of Natural Aura",
|
||||
"item.naturesaura.shockwave_creator": "Amulet of Wrath",
|
||||
"item.naturesaura.multiblock_maker": "Multiblock Maker",
|
||||
"item.naturesaura.vacuum_bottle": "Bottled Vacuum",
|
||||
"item.naturesaura.aura_bottle.naturesaura:overworld": "Bottled Sunlight",
|
||||
"item.naturesaura.aura_bottle.naturesaura:nether": "Bottled Ghosts",
|
||||
"item.naturesaura.aura_bottle.naturesaura:end": "Bottled Darkness",
|
||||
|
@ -191,11 +193,11 @@
|
|||
"advancement.naturesaura.infused_tools": "Gear Up Intensifies",
|
||||
"advancement.naturesaura.infused_tools.desc": "Create an Infused Iron Pickaxe and Blade",
|
||||
"advancement.naturesaura.aura_bottle_overworld": "A Taste of Sunlight",
|
||||
"advancement.naturesaura.aura_bottle_overworld.desc": "Collect Aura using a Bottle in the Overworld",
|
||||
"advancement.naturesaura.aura_bottle_overworld.desc": "Collect Aura using a Bottle and Cork in the Overworld",
|
||||
"advancement.naturesaura.aura_bottle_nether": "Spooky Scary Skeletons",
|
||||
"advancement.naturesaura.aura_bottle_nether.desc": "Collect Aura using a Bottle in the Nether",
|
||||
"advancement.naturesaura.aura_bottle_nether.desc": "Collect Aura using a Bottle and Cork in the Nether",
|
||||
"advancement.naturesaura.aura_bottle_end": "Breathy Surroundings",
|
||||
"advancement.naturesaura.aura_bottle_end.desc": "Collect Aura using a Bottle in the End",
|
||||
"advancement.naturesaura.aura_bottle_end.desc": "Collect Aura using a Bottle and Cork in the End",
|
||||
"advancement.naturesaura.offering": "Yo God, Ya Want This?",
|
||||
"advancement.naturesaura.offering.desc": "Create an Offering Table for the Offering to the Gods",
|
||||
"advancement.naturesaura.sky_ingot": "Sturdy and Light",
|
||||
|
@ -214,6 +216,8 @@
|
|||
"advancement.naturesaura.eye_improved.desc": "Create an Environmental Ocular to see Aura imbalance effects",
|
||||
"advancement.naturesaura.range_visualizer": "I Spy With my Little Eye",
|
||||
"advancement.naturesaura.range_visualizer.desc": "Create a Mystical Magnifier to see the range of your devices",
|
||||
"advancement.naturesaura.vacuum_bottle": "Breathe Through, Breathe Deep",
|
||||
"advancement.naturesaura.vacuum_bottle.desc": "Capture a vacuum using a Bottle and Cork",
|
||||
"command.naturesaura.aura.usage": "/naaura store|drain <amount> [range] OR /naaura reset <range>",
|
||||
"effect.naturesaura.breathless": "Breathless",
|
||||
"entity.naturesaura.effect_inhibitor": "Effect Powder",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"parent": "minecraft:block/block",
|
||||
"render_type": "translucent",
|
||||
"render_type": "cutout_mipped",
|
||||
"ambientocclusion": false,
|
||||
"textures": {
|
||||
"particle": "naturesaura:block/spring",
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"name": "Disentangler of Mortals",
|
||||
"icon": "naturesaura:animal_generator",
|
||||
"category": "naturesaura:creating",
|
||||
"advancement": "naturesaura:tainted_gold",
|
||||
"advancement": "naturesaura:infused_materials",
|
||||
"pages": [
|
||||
{
|
||||
"type": "text",
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"name": "Shooting Mark",
|
||||
"icon": "naturesaura:projectile_generator",
|
||||
"category": "naturesaura:creating",
|
||||
"advancement": "naturesaura:tainted_gold",
|
||||
"advancement": "naturesaura:infused_materials",
|
||||
"pages": [
|
||||
{
|
||||
"type": "text",
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"name": "Offshoot Observer",
|
||||
"icon": "naturesaura:slime_split_generator",
|
||||
"category": "naturesaura:creating",
|
||||
"advancement": "naturesaura:tainted_gold",
|
||||
"advancement": "naturesaura:infused_materials",
|
||||
"pages": [
|
||||
{
|
||||
"type": "text",
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"name": "Amulet of Wrath",
|
||||
"icon": "naturesaura:shockwave_creator",
|
||||
"category": "naturesaura:items",
|
||||
"advancement": "naturesaura:tainted_gold",
|
||||
"advancement": "naturesaura:infused_materials",
|
||||
"pages": [
|
||||
{
|
||||
"type": "text",
|
||||
|
|
|
@ -23,6 +23,12 @@
|
|||
{
|
||||
"type": "text",
|
||||
"text": "Additionally, the collection of $(aura) in this manner can be automated easily using $(item)Dispensers$(): Putting empty $(item)Bottles and Corks$() into them will cause them to be shot out open, making them fill up with $(aura) in the process. As they are not sucked up by the Dispenser again afterwards, an additional tool like a $(item)Hopper$() is required."
|
||||
},
|
||||
{
|
||||
"type": "spotlight",
|
||||
"item": "naturesaura:vacuum_bottle",
|
||||
"link_recipe": true,
|
||||
"text": "Lastly, some areas have a severe lack of $(aura), much lower than the $(l:items/eye)Environmental Eye$() can display, and whose air is subsequently nearly devoid of oxygen. Using a $(item)Bottle and Cork$() in areas like these allows bottling up this air and capturing a nearly perfect vacuum in the bottle."
|
||||
}
|
||||
]
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
"name": "Offering to the Gods",
|
||||
"icon": "naturesaura:offering_table",
|
||||
"category": "naturesaura:practices",
|
||||
"advancement": "naturesaura:tainted_gold",
|
||||
"advancement": "naturesaura:infused_materials",
|
||||
"pages": [
|
||||
{
|
||||
"type": "text",
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"name": "Aura Imbalance Ward",
|
||||
"icon": "naturesaura:lower_limiter",
|
||||
"category": "naturesaura:using",
|
||||
"advancement": "naturesaura:vacuum_bottle",
|
||||
"priority": true,
|
||||
"pages": [
|
||||
{
|
||||
"type": "text",
|
||||
"text": "As any magical botanist knows, causing negative $(aura) imbalance effects can be quite dangerous, especially when using a device that consumes $(aura) passively.$(br)For cases like this, the $(item)Aura Imbalance Ward$() provides protection against any dangers: placing it next to a device that uses $(aura) causes the device to cease operation while the $(aura) levels around it are too low.$(br)This comes at no cost in return."
|
||||
},
|
||||
{
|
||||
"type": "crafting",
|
||||
"recipe": "naturesaura:lower_limiter",
|
||||
"text": "Crafting the $(item)Aura Imbalance Ward$()"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
"name": "Amulet of Wrath",
|
||||
"icon": "naturesaura:shockwave_creator",
|
||||
"category": "naturesaura:items",
|
||||
"advancement": "naturesaura:tainted_gold",
|
||||
"advancement": "naturesaura:infused_materials",
|
||||
"pages": [
|
||||
{
|
||||
"type": "text",
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"name": "Offering to the Gods",
|
||||
"icon": "naturesaura:offering_table",
|
||||
"category": "naturesaura:practices",
|
||||
"advancement": "naturesaura:tainted_gold",
|
||||
"advancement": "naturesaura:infused_materials",
|
||||
"pages": [
|
||||
{
|
||||
"type": "text",
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"name": "分裂观测仪",
|
||||
"icon": "naturesaura:slime_split_generator",
|
||||
"category": "naturesaura:creating",
|
||||
"advancement": "naturesaura:tainted_gold",
|
||||
"advancement": "naturesaura:infused_materials",
|
||||
"pages": [
|
||||
{
|
||||
"type": "text",
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"name": "狂怒护身符",
|
||||
"icon": "naturesaura:shockwave_creator",
|
||||
"category": "naturesaura:items",
|
||||
"advancement": "naturesaura:tainted_gold",
|
||||
"advancement": "naturesaura:infused_materials",
|
||||
"pages": [
|
||||
{
|
||||
"type": "text",
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"name": "祭祀诸神",
|
||||
"icon": "naturesaura:offering_table",
|
||||
"category": "naturesaura:practices",
|
||||
"advancement": "naturesaura:tainted_gold",
|
||||
"advancement": "naturesaura:infused_materials",
|
||||
"pages": [
|
||||
{
|
||||
"type": "text",
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 690 B |
Binary file not shown.
After Width: | Height: | Size: 739 B |
Binary file not shown.
After Width: | Height: | Size: 270 B |
Binary file not shown.
After Width: | Height: | Size: 418 B |
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"display": {
|
||||
"icon": {
|
||||
"item": "naturesaura:vacuum_bottle"
|
||||
},
|
||||
"title": {
|
||||
"translate": "advancement.naturesaura.vacuum_bottle"
|
||||
},
|
||||
"description": {
|
||||
"translate": "advancement.naturesaura.vacuum_bottle.desc"
|
||||
}
|
||||
},
|
||||
"parent": "naturesaura:negative_imbalance",
|
||||
"criteria": {
|
||||
"bottle": {
|
||||
"trigger": "minecraft:inventory_changed",
|
||||
"conditions": {
|
||||
"items": [
|
||||
{
|
||||
"items": ["naturesaura:vacuum_bottle"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"type": "minecraft:crafting_shaped",
|
||||
"pattern": [
|
||||
"S1S",
|
||||
"2I3",
|
||||
"S4S"
|
||||
],
|
||||
"key": {
|
||||
"S": {
|
||||
"item": "naturesaura:infused_stone"
|
||||
},
|
||||
"1": {
|
||||
"item": "naturesaura:token_euphoria"
|
||||
},
|
||||
"2": {
|
||||
"item": "naturesaura:token_terror"
|
||||
},
|
||||
"3": {
|
||||
"item": "naturesaura:token_rage"
|
||||
},
|
||||
"4": {
|
||||
"item": "naturesaura:token_grief"
|
||||
},
|
||||
"I": {
|
||||
"item": "naturesaura:vacuum_bottle"
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"item": "naturesaura:lower_limiter"
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue