Skip to content

Commit 1e5bfb3

Browse files
authored
feat(multiblock): implement dynamic multiblock event handling for formation and unformation (#69)
1 parent d121047 commit 1e5bfb3

5 files changed

Lines changed: 84 additions & 5 deletions

File tree

module.multiblock/src/main/java/dev/anvilcraft/lib/v2/multiblock/dynamic/DynamicMultiblockManager.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import dev.anvilcraft.lib.v2.multiblock.dynamic.controller.ControllerRecord;
77
import dev.anvilcraft.lib.v2.multiblock.dynamic.controller.IController;
88
import dev.anvilcraft.lib.v2.multiblock.dynamic.definition.MultiblockDefinition;
9+
import dev.anvilcraft.lib.v2.multiblock.dynamic.event.DynamicMultiblockEvent;
910
import dev.anvilcraft.lib.v2.multiblock.init.LibRegistries;
1011
import dev.anvilcraft.lib.v2.multiblock.network.MultiblockFormPacket;
1112
import dev.anvilcraft.lib.v2.multiblock.network.MultiblockUnformPacket;
@@ -21,6 +22,7 @@
2122
import net.minecraft.world.level.block.state.BlockState;
2223
import net.minecraft.world.level.saveddata.SavedData;
2324
import net.minecraft.world.level.saveddata.SavedDataType;
25+
import net.neoforged.neoforge.common.NeoForge;
2426
import net.neoforged.neoforge.network.PacketDistributor;
2527
import org.jetbrains.annotations.UnknownNullability;
2628
import org.slf4j.Logger;
@@ -174,9 +176,23 @@ public void updateFormed(Level level, MultiblockState cur, boolean formed) {
174176
throw e;
175177
}
176178
if (formed) {
177-
controller.onFormed(level, cur);
179+
DynamicMultiblockEvent.Form event = new DynamicMultiblockEvent.Form(level, controller, cur);
180+
NeoForge.EVENT_BUS.post(event);
181+
if (!event.isCanceled()) {
182+
controller.onFormed(level, cur);
183+
} else {
184+
cur.setFormed(false);
185+
return;
186+
}
178187
} else {
179-
controller.onUnformed(level, cur);
188+
DynamicMultiblockEvent.Unform event = new DynamicMultiblockEvent.Unform(level, controller, cur);
189+
NeoForge.EVENT_BUS.post(event);
190+
if (!event.isCanceled()) {
191+
controller.onUnformed(level, cur);
192+
} else {
193+
cur.setFormed(true);
194+
return;
195+
}
180196
}
181197
}
182198

module.multiblock/src/main/java/dev/anvilcraft/lib/v2/multiblock/dynamic/controller/IController.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ public interface IController {
3535
default void onFormed(Level level, MultiblockState state) {
3636
}
3737

38-
3938
/**
4039
* 多方块未成型回调
4140
*
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package dev.anvilcraft.lib.v2.multiblock.dynamic.event;
2+
3+
import dev.anvilcraft.lib.v2.multiblock.dynamic.MultiblockState;
4+
import dev.anvilcraft.lib.v2.multiblock.dynamic.controller.IController;
5+
import lombok.Getter;
6+
import net.minecraft.world.level.Level;
7+
import net.neoforged.bus.api.Event;
8+
import net.neoforged.bus.api.ICancellableEvent;
9+
10+
/// 所有与动态多方块结构有关的事件的基类。
11+
@Getter
12+
public abstract class DynamicMultiblockEvent extends Event {
13+
private final Level level;
14+
private final IController controller;
15+
private final MultiblockState state;
16+
17+
protected DynamicMultiblockEvent(Level level, IController controller, MultiblockState state) {
18+
this.level = level;
19+
this.controller = controller;
20+
this.state = state;
21+
}
22+
23+
/// 本事件会在多方块结构尝试形成时发出。
24+
///
25+
/// 取消该事件将阻止多方块结构的形成。
26+
///
27+
/// 本事件会在双端发出。
28+
public static class Form extends DynamicMultiblockEvent implements ICancellableEvent {
29+
public Form(Level level, IController controller, MultiblockState state) {
30+
super(level, controller, state);
31+
}
32+
}
33+
34+
/// 本事件会在多方块结构尝试解散时发出。
35+
///
36+
/// 取消该事件将阻止多方块结构的解散。
37+
///
38+
/// 本事件会在双端发出。
39+
public static class Unform extends DynamicMultiblockEvent implements ICancellableEvent {
40+
public Unform(Level level, IController controller, MultiblockState state) {
41+
super(level, controller, state);
42+
}
43+
}
44+
}

module.multiblock/src/main/java/dev/anvilcraft/lib/v2/multiblock/network/MultiblockFormPacket.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import dev.anvilcraft.lib.v2.multiblock.dynamic.DynamicMultiblockManager;
55
import dev.anvilcraft.lib.v2.multiblock.dynamic.MultiblockState;
66
import dev.anvilcraft.lib.v2.multiblock.dynamic.controller.ControllerRecord;
7+
import dev.anvilcraft.lib.v2.multiblock.dynamic.controller.IController;
8+
import dev.anvilcraft.lib.v2.multiblock.dynamic.event.DynamicMultiblockEvent;
79
import dev.anvilcraft.lib.v2.network.packet.IClientboundPacket;
810
import dev.anvilcraft.lib.v2.network.packet.IPacket;
911
import lombok.extern.slf4j.Slf4j;
@@ -14,6 +16,7 @@
1416
import net.minecraft.world.entity.player.Player;
1517
import net.minecraft.world.level.Level;
1618
import net.minecraft.world.level.block.state.BlockState;
19+
import net.neoforged.neoforge.common.NeoForge;
1720

1821
@Slf4j
1922
@SuppressWarnings("unused")
@@ -40,7 +43,14 @@ public void handleOnClient(Player player) {
4043
BlockState state = level.getBlockState(pos);
4144
if (!this.state.getDefinition(level.registryAccess()).value().isController(level, state, level.getBlockEntity(pos))) return;
4245
try {
43-
ControllerRecord.get(state.getBlock(), this.state.getDefinitionKey().identifier()).onFormed(level, this.state);
46+
IController controller = ControllerRecord.get(state.getBlock(), this.state.getDefinitionKey().identifier());
47+
DynamicMultiblockEvent.Form event = new DynamicMultiblockEvent.Form(level, controller, this.state);
48+
NeoForge.EVENT_BUS.post(event);
49+
if (!event.isCanceled()) {
50+
controller.onFormed(level, this.state);
51+
} else {
52+
this.state.setFormed(false);
53+
}
4454
} catch (IllegalArgumentException e) {
4555
log.error(e.getLocalizedMessage(), e);
4656
throw e;

module.multiblock/src/main/java/dev/anvilcraft/lib/v2/multiblock/network/MultiblockUnformPacket.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import dev.anvilcraft.lib.v2.multiblock.dynamic.DynamicMultiblockManager;
55
import dev.anvilcraft.lib.v2.multiblock.dynamic.MultiblockState;
66
import dev.anvilcraft.lib.v2.multiblock.dynamic.controller.ControllerRecord;
7+
import dev.anvilcraft.lib.v2.multiblock.dynamic.controller.IController;
8+
import dev.anvilcraft.lib.v2.multiblock.dynamic.event.DynamicMultiblockEvent;
79
import dev.anvilcraft.lib.v2.network.packet.IClientboundPacket;
810
import dev.anvilcraft.lib.v2.network.packet.IPacket;
911
import lombok.extern.slf4j.Slf4j;
@@ -14,6 +16,7 @@
1416
import net.minecraft.world.entity.player.Player;
1517
import net.minecraft.world.level.Level;
1618
import net.minecraft.world.level.block.state.BlockState;
19+
import net.neoforged.neoforge.common.NeoForge;
1720

1821
@Slf4j
1922
@SuppressWarnings("unused")
@@ -40,7 +43,14 @@ public void handleOnClient(Player player) {
4043
BlockState state = level.getBlockState(pos);
4144
if (!this.state.getDefinition(level.registryAccess()).value().isController(level, state, level.getBlockEntity(pos))) return;
4245
try {
43-
ControllerRecord.get(state.getBlock(), this.state.getDefinitionKey().identifier()).onUnformed(level, this.state);
46+
IController controller = ControllerRecord.get(state.getBlock(), this.state.getDefinitionKey().identifier());
47+
DynamicMultiblockEvent.Unform event = new DynamicMultiblockEvent.Unform(level, controller, this.state);
48+
NeoForge.EVENT_BUS.post(event);
49+
if (!event.isCanceled()) {
50+
controller.onUnformed(level, this.state);
51+
} else {
52+
this.state.setFormed(true);
53+
}
4454
} catch (IllegalArgumentException e) {
4555
log.error(e.getLocalizedMessage(), e);
4656
throw e;

0 commit comments

Comments
 (0)