/
BlockPhysicsScriptEvent.java
106 lines (95 loc) · 4.02 KB
/
BlockPhysicsScriptEvent.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
package com.denizenscript.denizen.events.block;
import com.denizenscript.denizen.objects.LocationTag;
import com.denizenscript.denizen.objects.MaterialTag;
import com.denizenscript.denizen.events.BukkitScriptEvent;
import com.denizenscript.denizencore.utilities.debugging.Debug;
import com.denizenscript.denizencore.objects.ObjectTag;
import com.denizenscript.denizencore.utilities.ReflectionHelper;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.data.BlockData;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockPhysicsEvent;
import java.lang.reflect.Field;
public class BlockPhysicsScriptEvent extends BukkitScriptEvent implements Listener {
// <--[event]
// @Events
// <block> physics
//
// @Group Block
//
// @Location true
//
// @Warning This event may fire very rapidly.
//
// @Switch adjacent:<block> to only process the event if the block or an immediately adjacent block (up/down/n/e/s/w) matches the LocationTag matcher specified. This can be useful to prevent blocks from breaking.
//
// @Cancellable true
//
// @Triggers when a block's physics update.
//
// @Context
// <context.location> returns a LocationTag of the block the physics is affecting.
// <context.new_material> returns a MaterialTag of what the block is becoming.
//
// -->
public BlockPhysicsScriptEvent() {
registerCouldMatcher("<block> physics");
registerSwitches("adjacent");
}
public LocationTag location;
public MaterialTag material;
public BlockPhysicsEvent event;
@Override
public boolean matches(ScriptPath path) {
if (!runInCheck(path, location)) {
return false;
}
if (!material.tryAdvancedMatcher(path.eventArgLowerAt(0))) {
return false;
}
String adjacent = path.switches.get("adjacent");
if (adjacent != null) {
if (!material.tryAdvancedMatcher(adjacent)) {
Block block = location.getBlock();
if (!new LocationTag(block.getRelative(0, 1, 0).getLocation()).tryAdvancedMatcher(adjacent)
&& !new LocationTag(block.getRelative(0, -1, 0).getLocation()).tryAdvancedMatcher(adjacent)
&& !new LocationTag(block.getRelative(1, 0, 0).getLocation()).tryAdvancedMatcher(adjacent)
&& !new LocationTag(block.getRelative(-1, 0, 0).getLocation()).tryAdvancedMatcher(adjacent)
&& !new LocationTag(block.getRelative(0, 0, 1).getLocation()).tryAdvancedMatcher(adjacent)
&& !new LocationTag(block.getRelative(0, 0, -1).getLocation()).tryAdvancedMatcher(adjacent)) {
return false;
}
}
}
return super.matches(path);
}
public static Field PHYSICS_EVENT_DATA = ReflectionHelper.getFields(BlockPhysicsEvent.class).getFirstOfType(BlockData.class);
@Override
public ObjectTag getContext(String name) {
switch (name) {
case "location": return location;
case "new_material":
try {
BlockData data = (BlockData) PHYSICS_EVENT_DATA.get(event);
return new MaterialTag(data);
}
catch (Throwable ex) {
Debug.echoError(ex);
}
}
return super.getContext(name);
}
@EventHandler
public void onBlockPhysics(BlockPhysicsEvent event) {
Material changedType = event.getChangedType();
if (changedType == Material.REDSTONE_WIRE || changedType == Material.COMPARATOR || changedType == Material.REPEATER) {
return;
}
location = new LocationTag(event.getBlock().getLocation());
material = new MaterialTag(location.getBlock());
this.event = event;
fire(event);
}
}