/
ToolActionTransformModule.java
129 lines (114 loc) · 5.04 KB
/
ToolActionTransformModule.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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package slimeknights.tconstruct.library.modifiers.modules.behavior;
import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.experimental.Accessors;
import net.minecraft.core.BlockPos;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Material;
import net.minecraftforge.common.ToolAction;
import slimeknights.mantle.data.loadable.Loadables;
import slimeknights.mantle.data.loadable.primitive.BooleanLoadable;
import slimeknights.mantle.data.loadable.primitive.IntLoadable;
import slimeknights.mantle.data.loadable.record.RecordLoadable;
import slimeknights.mantle.data.registry.GenericLoaderRegistry.IGenericLoader;
import slimeknights.tconstruct.library.modifiers.ModifierEntry;
import slimeknights.tconstruct.library.modifiers.ModifierHook;
import slimeknights.tconstruct.library.modifiers.TinkerHooks;
import slimeknights.tconstruct.library.modifiers.hook.behavior.ToolActionModifierHook;
import slimeknights.tconstruct.library.modifiers.hook.special.BlockTransformModifierHook;
import slimeknights.tconstruct.library.modifiers.modules.ModifierModule;
import slimeknights.tconstruct.library.modifiers.modules.ModifierModuleCondition;
import slimeknights.tconstruct.library.modifiers.modules.ModifierModuleCondition.ConditionalModifierModule;
import slimeknights.tconstruct.library.tools.nbt.IToolStackView;
import java.util.List;
/**
* Module which transforms a block using a tool action
*/
public record ToolActionTransformModule(ToolAction action, SoundEvent sound, boolean requireGround, int eventId, ModifierModuleCondition condition) implements BlockTransformModule, ToolActionModifierHook, ConditionalModifierModule {
private static final List<ModifierHook<?>> DEFAULT_HOOKS = List.of(TinkerHooks.BLOCK_INTERACT, TinkerHooks.TOOL_ACTION);
public static final RecordLoadable<ToolActionTransformModule> LOADER = RecordLoadable.create(
Loadables.TOOL_ACTION.requiredField("tool_action", ToolActionTransformModule::action),
Loadables.SOUND_EVENT.requiredField("sound", ToolActionTransformModule::sound),
BooleanLoadable.INSTANCE.requiredField("require_ground", ToolActionTransformModule::requireGround),
IntLoadable.FROM_MINUS_ONE.defaultField("event_id", -1, ToolActionTransformModule::eventId),
ModifierModuleCondition.FIELD,
ToolActionTransformModule::new);
@Override
public List<ModifierHook<?>> getDefaultHooks() {
return DEFAULT_HOOKS;
}
@Override
public boolean canPerformAction(IToolStackView tool, ModifierEntry modifier, ToolAction toolAction) {
return condition.matches(tool, modifier) && this.action == toolAction;
}
@Override
public boolean transform(IToolStackView tool, UseOnContext context, BlockState original, boolean playSound) {
Level level = context.getLevel();
BlockPos pos = context.getClickedPos();
BlockPos above = pos.above();
// hoes and shovels: air or plants above
if (requireGround) {
Material material = level.getBlockState(above).getMaterial();
if (!material.isReplaceable() && material != Material.PLANT) {
return false;
}
}
// normal action transform
Player player = context.getPlayer();
BlockState transformed = original.getToolModifiedState(context, action, false);
if (transformed != null) {
if (playSound) {
level.playSound(player, pos, sound, SoundSource.BLOCKS, 1.0F, 1.0F);
if (eventId != -1) {
level.levelEvent(player, eventId, pos, 0);
}
}
if (!level.isClientSide) {
level.setBlock(pos, transformed, Block.UPDATE_ALL_IMMEDIATE);
if (requireGround) {
level.destroyBlock(above, true);
}
BlockTransformModifierHook.afterTransformBlock(tool, context, original, pos, action);
}
return true;
}
return false;
}
@Override
public IGenericLoader<? extends ModifierModule> getLoader() {
return LOADER;
}
/* Builder */
public static Builder builder(ToolAction action, SoundEvent sound) {
return new Builder(action, sound);
}
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public static class Builder extends ModifierModuleCondition.Builder<Builder> {
private final ToolAction action;
private final SoundEvent sound;
private boolean requireGround;
/**
* Event ID to play upon success
* @see Level#levelEvent(int, BlockPos, int)
*/
@Setter
@Accessors(fluent = true)
private int eventId = -1;
/** Sets the module to require the block above to be empty */
public Builder requireGround() {
this.requireGround = true;
return this;
}
/** Builds the module */
public ToolActionTransformModule build() {
return new ToolActionTransformModule(action, sound, requireGround, eventId, condition);
}
}
}