lower limiter, part 1

This commit is contained in:
Ell 2023-02-16 19:03:26 +01:00
parent 7d23cafc77
commit b3f2a61e5d
34 changed files with 360 additions and 107 deletions

View file

@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "naturesaura:block/lower_limiter"
}
}
}

View file

@ -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"
}
}

View file

@ -0,0 +1,3 @@
{
"parent": "naturesaura:block/lower_limiter"
}

View file

@ -1,15 +1,15 @@
{
"values": [
"naturesaura:ancient_log",
"naturesaura:ancient_slab",
"naturesaura:ancient_stairs",
"naturesaura:nether_wart_mushroom",
"naturesaura:oak_generator",
"naturesaura:auto_crafter",
"naturesaura:flower_generator",
"naturesaura:wood_stand",
"naturesaura:ancient_bark",
"naturesaura:ancient_planks",
"naturesaura:nether_wart_mushroom",
"naturesaura:offering_table",
"naturesaura:ancient_log"
"naturesaura:ancient_stairs",
"naturesaura:flower_generator",
"naturesaura:wood_stand",
"naturesaura:offering_table"
]
}

View file

@ -1,46 +1,47 @@
{
"values": [
"naturesaura:nature_altar",
"naturesaura:animal_spawner",
"naturesaura:chorus_generator",
"naturesaura:animal_container",
"naturesaura:infused_slab",
"naturesaura:potion_generator",
"naturesaura:grated_chute",
"naturesaura:ender_crate",
"naturesaura:generator_limit_remover",
"naturesaura:gold_brick",
"naturesaura:spring",
"naturesaura:infused_stairs",
"naturesaura:potion_generator",
"naturesaura:infused_brick_stairs",
"naturesaura:aura_detector",
"naturesaura:spawn_lamp",
"naturesaura:hopper_upgrade",
"naturesaura:pickup_stopper",
"naturesaura:infused_brick_slab",
"naturesaura:field_creator",
"naturesaura:item_distributor",
"naturesaura:moss_generator",
"naturesaura:spring",
"naturesaura:conversion_catalyst",
"naturesaura:firework_generator",
"naturesaura:aura_timer",
"naturesaura:animal_container",
"naturesaura:powder_placer",
"naturesaura:infused_iron_block",
"naturesaura:weather_changer",
"naturesaura:gold_nether_brick",
"naturesaura:grated_chute",
"naturesaura:crushing_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:furnace_heater",
"naturesaura:nether_grass",
"naturesaura:projectile_generator",
"naturesaura:animal_generator",
"naturesaura:infused_brick_stairs",
"naturesaura:crushing_catalyst",
"naturesaura:infused_brick",
"naturesaura:field_creator",
"naturesaura:nature_altar",
"naturesaura:gold_nether_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:blast_furnace_booster",
"naturesaura:placer",
"naturesaura:item_distributor",
"naturesaura:time_changer",
"naturesaura:tainted_gold_block",
"naturesaura:gold_brick"
"naturesaura:conversion_catalyst",
"naturesaura:hopper_upgrade",
"naturesaura:pickup_stopper",
"naturesaura:infused_brick",
"naturesaura:generator_limit_remover",
"naturesaura:infused_slab"
]
}

View file

@ -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
}
]
}

View file

@ -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);

View file

@ -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);
}

View file

@ -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);
}
}

View file

@ -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));
}

View file

@ -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

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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));
}
}

View file

@ -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())

View file

@ -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;
}
}

View file

@ -39,4 +39,9 @@ public class BlockEntitySpawnLamp extends BlockEntityImpl {
if (!this.level.isClientSide)
this.sendToClients();
}
@Override
public boolean allowsLowerLimiter() {
return true;
}
}

View file

@ -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);
}

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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;
}

View file

@ -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);
RenderGeneratorLimitRemover.renderGlint(matrixStack, iRenderTypeBuffer, this.model, 0, 0, 0, combinedOverlayIn, RenderGeneratorLimitRemover.RES);
}
}
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) {
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.001F + xOff, 1 + 0.001F + yOff, 1 + 0.001F + 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);
model.renderToBuffer(stack, buffer.getBuffer(model.renderType(texture)), brightness, combinedOverlayIn, 1, 1, 1, alpha);
stack.popPose();
}
private static class ModelLimitRemoverGlint extends Model {
public static class ModelLimitRemoverGlint extends Model {
private final ModelPart model;

View file

@ -0,0 +1,36 @@
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 entity = te.getLevel().getBlockEntity(te.getBlockPos().relative(dir));
if (entity instanceof BlockEntityImpl impl && impl.allowsLowerLimiter()) {
RenderGeneratorLimitRemover.renderGlint(matrixStack, iRenderTypeBuffer, this.model, dir.getStepX(), dir.getStepY(), dir.getStepZ(), combinedOverlayIn, RenderLowerLimiter.RES);
RenderGeneratorLimitRemover.renderGlint(matrixStack, iRenderTypeBuffer, this.model, 0, 0, 0, combinedOverlayIn, RenderLowerLimiter.RES);
}
}
}
}

View file

@ -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());
});

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: 418 B