-
Notifications
You must be signed in to change notification settings - Fork 755
/
OffhandAttackModifier.java
97 lines (86 loc) · 4.79 KB
/
OffhandAttackModifier.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
package slimeknights.tconstruct.tools.modifiers.ability.tool;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.player.Player;
import slimeknights.mantle.util.OffhandCooldownTracker;
import slimeknights.tconstruct.TConstruct;
import slimeknights.tconstruct.library.modifiers.ModifierEntry;
import slimeknights.tconstruct.library.modifiers.ModifierHooks;
import slimeknights.tconstruct.library.modifiers.hook.armor.EquipmentChangeModifierHook;
import slimeknights.tconstruct.library.modifiers.hook.build.VolatileDataModifierHook;
import slimeknights.tconstruct.library.modifiers.hook.interaction.EntityInteractionModifierHook;
import slimeknights.tconstruct.library.modifiers.hook.interaction.GeneralInteractionModifierHook;
import slimeknights.tconstruct.library.modifiers.hook.interaction.InteractionSource;
import slimeknights.tconstruct.library.modifiers.impl.NoLevelsModifier;
import slimeknights.tconstruct.library.modifiers.modules.behavior.ShowOffhandModule;
import slimeknights.tconstruct.library.module.ModuleHookMap.Builder;
import slimeknights.tconstruct.library.tools.context.EquipmentChangeContext;
import slimeknights.tconstruct.library.tools.helper.ToolAttackUtil;
import slimeknights.tconstruct.library.tools.nbt.IToolContext;
import slimeknights.tconstruct.library.tools.nbt.IToolStackView;
import slimeknights.tconstruct.library.tools.nbt.ModDataNBT;
import slimeknights.tconstruct.library.tools.stat.ToolStats;
public class OffhandAttackModifier extends NoLevelsModifier implements EntityInteractionModifierHook, GeneralInteractionModifierHook, EquipmentChangeModifierHook, VolatileDataModifierHook {
public static final ResourceLocation DUEL_WIELDING = TConstruct.getResource("duel_wielding");
@Override
protected void registerHooks(Builder hookBuilder) {
super.registerHooks(hookBuilder);
hookBuilder.addHook(this, ModifierHooks.GENERAL_INTERACT, ModifierHooks.ENTITY_INTERACT, ModifierHooks.EQUIPMENT_CHANGE, ModifierHooks.VOLATILE_DATA);
hookBuilder.addModule(ShowOffhandModule.DISALLOW_BROKEN);
}
@Override
public int getPriority() {
return 90;
}
@Override
public boolean shouldDisplay(boolean advanced) {
return false;
}
@Override
public void addVolatileData(IToolContext context, ModifierEntry modifier, ModDataNBT volatileData) {
volatileData.putBoolean(DUEL_WIELDING, true);
}
/** If true, we can use the attack */
protected boolean canAttack(IToolStackView tool, Player player, InteractionHand hand) {
return !tool.isBroken() && hand == InteractionHand.OFF_HAND && OffhandCooldownTracker.isAttackReady(player);
}
@Override
public InteractionResult beforeEntityUse(IToolStackView tool, ModifierEntry modifier, Player player, Entity target, InteractionHand hand, InteractionSource source) {
if (canAttack(tool, player, hand)) {
if (!player.level.isClientSide()) {
ToolAttackUtil.attackEntity(tool, player, InteractionHand.OFF_HAND, target, ToolAttackUtil.getCooldownFunction(player, InteractionHand.OFF_HAND), false, source.getSlot(hand));
}
OffhandCooldownTracker.applyCooldown(player, tool.getStats().get(ToolStats.ATTACK_SPEED), 20);
// we handle swinging the arm, return consume to prevent resetting cooldown
OffhandCooldownTracker.swingHand(player, InteractionHand.OFF_HAND, false);
return InteractionResult.CONSUME;
}
return InteractionResult.PASS;
}
@Override
public InteractionResult onToolUse(IToolStackView tool, ModifierEntry modifier, Player player, InteractionHand hand, InteractionSource source) {
if (canAttack(tool, player, hand)) {
// target done in onEntityInteract, this is just for cooldown cause you missed
OffhandCooldownTracker.applyCooldown(player, tool.getStats().get(ToolStats.ATTACK_SPEED), 20);
// we handle swinging the arm, return consume to prevent resetting cooldown
OffhandCooldownTracker.swingHand(player, InteractionHand.OFF_HAND, false);
return InteractionResult.CONSUME;
}
return InteractionResult.PASS;
}
@Override
public void onEquip(IToolStackView tool, ModifierEntry modifier, EquipmentChangeContext context) {
if (!tool.isBroken() && context.getChangedSlot() == EquipmentSlot.OFFHAND) {
context.getEntity().getCapability(OffhandCooldownTracker.CAPABILITY).ifPresent(cap -> cap.setEnabled(true));
}
}
@Override
public void onUnequip(IToolStackView tool, ModifierEntry modifier, EquipmentChangeContext context) {
if (!tool.isBroken() && context.getChangedSlot() == EquipmentSlot.OFFHAND) {
context.getEntity().getCapability(OffhandCooldownTracker.CAPABILITY).ifPresent(cap -> cap.setEnabled(false));
}
}
}