Skip to content

Commit

Permalink
Add event to allow addons to spawn additional "grid tools" into a che…
Browse files Browse the repository at this point in the history
…st next to a test-plot (#7760)
  • Loading branch information
shartte authored Mar 13, 2024
1 parent 1650b1c commit fc8c1b4
Show file tree
Hide file tree
Showing 9 changed files with 221 additions and 37 deletions.
13 changes: 13 additions & 0 deletions src/main/java/appeng/server/testplots/AutoCraftingTestPlots.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import net.minecraft.world.item.crafting.RecipeType;
import net.minecraft.world.level.ItemLike;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.material.Fluids;

import appeng.api.config.Actionable;
Expand All @@ -24,13 +25,15 @@
import appeng.blockentity.crafting.PatternProviderBlockEntity;
import appeng.blockentity.misc.InscriberBlockEntity;
import appeng.blockentity.storage.SkyChestBlockEntity;
import appeng.core.AppEng;
import appeng.core.definitions.AEBlocks;
import appeng.core.definitions.AEItems;
import appeng.core.definitions.AEParts;
import appeng.items.storage.CreativeCellItem;
import appeng.me.helpers.BaseActionSource;
import appeng.menu.AutoCraftingMenu;
import appeng.server.testworld.PlotBuilder;
import appeng.server.testworld.SpawnExtraGridTestToolsChest;
import appeng.server.testworld.TestCraftingJob;
import appeng.util.inv.AppEngInternalInventory;

Expand Down Expand Up @@ -66,6 +69,7 @@ public static void create(PlotBuilder plot) {
drive.getInternalInventory().addItems(CreativeCellItem.ofItems(Items.REDSTONE));
drive.getInternalInventory().addItems(CreativeCellItem.ofFluids(Fluids.LAVA));
});
plot.block("7 -1 0", AEBlocks.CELL_WORKBENCH);
plot.part("6 0 1", Direction.NORTH, AEParts.PATTERN_ENCODING_TERMINAL, term -> {
var inv = term.getLogic().getBlankPatternInv();
inv.addItems(AEItems.BLANK_PATTERN.stack(64));
Expand All @@ -74,6 +78,15 @@ public static void create(PlotBuilder plot) {
plot.part("4 0 1", Direction.NORTH, AEParts.TERMINAL);
plot.part("3 0 1", Direction.NORTH, AEParts.CRAFTING_TERMINAL);

// Wireless access
plot.blockState("6 1 1", AEBlocks.WIRELESS_ACCESS_POINT.block()
.defaultBlockState()
.setValue(BlockStateProperties.FACING, Direction.UP));
plot.addBuildAction(new SpawnExtraGridTestToolsChest(
new BlockPos(8, 0, 1),
new BlockPos(7, 0, 1),
AppEng.makeId("autocrafting_testplot")));

// Subsystem to craft obsidian
buildObsidianCrafting(plot.offset(3, 0, 5));

Expand Down
34 changes: 34 additions & 0 deletions src/main/java/appeng/server/testplots/SpawnExtraGridTestTools.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package appeng.server.testplots;

import net.minecraft.resources.ResourceLocation;
import net.neoforged.bus.api.Event;

import appeng.api.inventories.InternalInventory;
import appeng.api.networking.IGrid;

/**
* Triggered to spawn additional testing tools into a container placed next to a spawned AE2 grid.
*/
public class SpawnExtraGridTestTools extends Event {
private final ResourceLocation plotId;
private final InternalInventory inventory;
private final IGrid grid;

public SpawnExtraGridTestTools(ResourceLocation plotId, InternalInventory inventory, IGrid grid) {
this.plotId = plotId;
this.inventory = inventory;
this.grid = grid;
}

public ResourceLocation getPlotId() {
return plotId;
}

public InternalInventory getInventory() {
return inventory;
}

public IGrid getGrid() {
return grid;
}
}
38 changes: 38 additions & 0 deletions src/main/java/appeng/server/testplots/SpawnTestTools.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package appeng.server.testplots;

import java.util.List;

import net.minecraft.core.GlobalPos;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.Mod;

import appeng.api.config.Actionable;
import appeng.api.features.GridLinkables;
import appeng.blockentity.networking.WirelessAccessPointBlockEntity;
import appeng.core.definitions.AEItems;

@Mod.EventBusSubscriber
public final class SpawnTestTools {

@SubscribeEvent
public static void spawnWirelessTerminals(SpawnExtraGridTestTools e) {
// Find a suitable WAP to link to
var waps = e.getGrid().getMachines(WirelessAccessPointBlockEntity.class);
if (waps.isEmpty()) {
return;
}

var wap = waps.iterator().next();
var inventory = e.getInventory();

for (var item : List.of(AEItems.WIRELESS_CRAFTING_TERMINAL, AEItems.WIRELESS_TERMINAL)) {
var terminal = item.stack();
// Fully charge it
item.asItem().injectAEPower(terminal, Double.MAX_VALUE, Actionable.MODULATE);
// Link it to the WAP we just placed
GridLinkables.get(item).link(terminal, GlobalPos.of(wap.getLevel().dimension(), wap.getBlockPos()));
inventory.addItems(terminal);
}
}

}
2 changes: 1 addition & 1 deletion src/main/java/appeng/server/testworld/BuildAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.levelgen.structure.BoundingBox;

interface BuildAction {
public interface BuildAction {
BoundingBox getBoundingBox();

default void build(ServerLevel level, Player player, BlockPos origin) {
Expand Down
53 changes: 53 additions & 0 deletions src/main/java/appeng/server/testworld/GridInitHelper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package appeng.server.testworld;

import java.util.function.BiConsumer;

import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;

import appeng.api.networking.IGrid;
import appeng.api.networking.IGridNode;
import appeng.blockentity.networking.CableBusBlockEntity;
import appeng.hooks.ticking.TickHandler;
import appeng.me.helpers.IGridConnectedBlockEntity;

final class GridInitHelper {

static void doAfterGridInit(ServerLevel level, BlockPos pos, boolean waitForActive,
BiConsumer<IGrid, IGridNode> consumer) {
Runnable delayedAction = new Runnable() {
private int attempts = 120;

@Override
public void run() {
// Check if there's a grid node there
var be = level.getBlockEntity(pos);
IGridNode gridNode = null;
if (be instanceof IGridConnectedBlockEntity host) {
gridNode = host.getMainNode().getNode();
} else if (be instanceof CableBusBlockEntity cableBus) {
var centerPart = cableBus.getCableBus().getPart(null);
if (centerPart != null) {
gridNode = centerPart.getGridNode();
} else {
return; // Stop -> not eligible
}
} else {
return; // Stop -> not eligible
}

if (gridNode == null || waitForActive && !gridNode.isActive()) {
if (--attempts > 0) {
TickHandler.instance().addCallable(level, this);
} else {
throw new IllegalStateException("Couldn't access grid node @ " + pos);
}
} else {
consumer.accept(gridNode.getGrid(), gridNode);
}
}
};
TickHandler.instance().addCallable(level, delayedAction);
}

}
32 changes: 32 additions & 0 deletions src/main/java/appeng/server/testworld/PlaceItemFrameAction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package appeng.server.testworld;

import java.util.List;
import java.util.function.Consumer;

import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.decoration.ItemFrame;
import net.minecraft.world.level.levelgen.structure.BoundingBox;

public record PlaceItemFrameAction(BlockPos pos, Direction facing,
Consumer<ItemFrame> customizer) implements BuildAction {
@Override
public BoundingBox getBoundingBox() {
return new BoundingBox(pos);
}

@Override
public void spawnEntities(ServerLevel level, BlockPos origin, List<Entity> entities) {
var actualPos = pos.offset(origin);

var itemFrame = new ItemFrame(EntityType.ITEM_FRAME, level, actualPos, facing);
if (!level.addFreshEntity(itemFrame)) {
return;
}
customizer.accept(itemFrame);
entities.add(itemFrame);
}
}
9 changes: 9 additions & 0 deletions src/main/java/appeng/server/testworld/PlotBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,15 @@ default void fencedEntity(BlockPos pos, EntityType<?> entity) {
});
}

default void entity(BlockPos pos, EntityType<?> entity) {
entity(pos, entity, e -> {
});
}

default void entity(BlockPos pos, EntityType<?> entity, Consumer<Entity> postProcessor) {
addBuildAction(new SpawnEntityAction(bb(posToBb(pos)), entity, postProcessor));
}

default void fencedEntity(BlockPos pos, EntityType<?> entity, Consumer<Entity> postProcessor) {
var subPlot = offset(pos.getX(), pos.getY(), pos.getZ());
subPlot.block("[-1,1] -1 [-1,1]", Blocks.STONE);
Expand Down
37 changes: 1 addition & 36 deletions src/main/java/appeng/server/testworld/PostGridInitAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,49 +9,14 @@

import appeng.api.networking.IGrid;
import appeng.api.networking.IGridNode;
import appeng.blockentity.networking.CableBusBlockEntity;
import appeng.hooks.ticking.TickHandler;
import appeng.me.helpers.IGridConnectedBlockEntity;

public record PostGridInitAction(BoundingBox bb,
BiConsumer<IGrid, IGridNode> consumer,
boolean waitForActive) implements BlockPlacingBuildAction {

@Override
public void placeBlock(ServerLevel level, Player player, BlockPos pos, BlockPos minPos, BlockPos maxPos) {
Runnable delayedAction = new Runnable() {
private int attempts = 120;

@Override
public void run() {
// Check if there's a grid node there
var be = level.getBlockEntity(pos);
IGridNode gridNode = null;
if (be instanceof IGridConnectedBlockEntity host) {
gridNode = host.getMainNode().getNode();
} else if (be instanceof CableBusBlockEntity cableBus) {
var centerPart = cableBus.getCableBus().getPart(null);
if (centerPart != null) {
gridNode = centerPart.getGridNode();
} else {
return; // Stop -> not eligible
}
} else {
return; // Stop -> not eligible
}

if (gridNode == null || waitForActive && !gridNode.isActive()) {
if (--attempts > 0) {
TickHandler.instance().addCallable(level, this);
} else {
throw new IllegalStateException("Couldn't access grid node @ " + pos);
}
} else {
consumer.accept(gridNode.getGrid(), gridNode);
}
}
};
TickHandler.instance().addCallable(level, delayedAction);
GridInitHelper.doAfterGridInit(level, pos, waitForActive, consumer);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package appeng.server.testworld;

import net.minecraft.core.BlockPos;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.levelgen.structure.BoundingBox;
import net.neoforged.neoforge.common.NeoForge;

import appeng.core.definitions.AEBlockEntities;
import appeng.core.definitions.AEBlocks;
import appeng.server.testplots.SpawnExtraGridTestTools;

/**
* Spawns a sky stone chest at the given position and once the grid at another position is initialized, posts
* {@link SpawnExtraGridTestTools} to allow the chest to be populated.
*/
public record SpawnExtraGridTestToolsChest(BlockPos chestPos, BlockPos gridPos,
ResourceLocation plotId) implements BuildAction {
@Override
public BoundingBox getBoundingBox() {
return new BoundingBox(chestPos);
}

@Override
public void build(ServerLevel level, Player player, BlockPos origin) {
var absChestPod = chestPos.offset(origin);
var absGridPos = gridPos.offset(origin);
level.setBlock(absChestPod, AEBlocks.SMOOTH_SKY_STONE_CHEST.block().defaultBlockState(), Block.UPDATE_ALL);

GridInitHelper.doAfterGridInit(level, absGridPos, false, (grid, gridNode) -> {
var chestOpt = level.getBlockEntity(absChestPod, AEBlockEntities.SKY_CHEST);
chestOpt.ifPresent(chest -> {
var inventory = chest.getInternalInventory();
NeoForge.EVENT_BUS.post(new SpawnExtraGridTestTools(plotId, inventory, grid));
});
});
}
}

0 comments on commit fc8c1b4

Please sign in to comment.