Skip to content

Commit

Permalink
Migrate several interaction modifiers to the new hook for the sake of…
Browse files Browse the repository at this point in the history
… left click support

Bows now can properly use glowing, block transforming, and bucketing
  • Loading branch information
KnightMiner committed Dec 19, 2022
1 parent 51909b6 commit f00755a
Show file tree
Hide file tree
Showing 11 changed files with 143 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@

import lombok.AllArgsConstructor;
import lombok.Getter;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.Level;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.eventbus.api.Event;
import slimeknights.tconstruct.library.modifiers.hook.interaction.InteractionSource;
import slimeknights.tconstruct.library.tools.nbt.IToolStackView;
import slimeknights.tconstruct.library.tools.nbt.ToolStack;

Expand All @@ -39,17 +40,42 @@ public static class ToolHarvestEvent extends TinkerToolEvent {
private final ServerLevel world;
private final BlockState state;
private final BlockPos pos;
private final InteractionSource source;
/** @deprecated use {@link #getSource()} */
@Deprecated
private final EquipmentSlot slotType;

/** @deprecated use {@link #ToolHarvestEvent(IToolStackView, UseOnContext, ServerLevel, BlockState, BlockPos, InteractionSource)} */
@Deprecated
public ToolHarvestEvent(IToolStackView tool, UseOnContext context, ServerLevel world, BlockState state, BlockPos pos, EquipmentSlot slotType) {
super(getItem(context, slotType), tool);
this.context = context;
this.world = world;
this.state = state;
this.pos = pos;
this.source = InteractionSource.fromEquipmentSlot(slotType);
this.slotType = slotType;
}

public ToolHarvestEvent(IToolStackView tool, UseOnContext context, ServerLevel world, BlockState state, BlockPos pos, InteractionSource source) {
super(getItem(context, source), tool);
this.context = context;
this.world = world;
this.state = state;
this.pos = pos;
this.source = source;
this.slotType = source.getSlot(context.getHand());
}

/** Gets the item for the event */
private static ItemStack getItem(UseOnContext context, InteractionSource source) {
Player player = context.getPlayer();
if (player != null) {
return player.getItemBySlot(source.getSlot(context.getHand()));
}
return context.getItemInHand();
}

/** Gets the item for the event */
private static ItemStack getItem(UseOnContext context, EquipmentSlot slotType) {
Player player = context.getPlayer();
Expand Down Expand Up @@ -94,6 +120,5 @@ public Result fire() {
MinecraftForge.EVENT_BUS.post(this);
return this.getResult();
}

}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package slimeknights.tconstruct.library.modifiers.dynamic;

import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.player.Player;
import slimeknights.mantle.client.TooltipKey;
Expand All @@ -10,12 +12,14 @@
import slimeknights.tconstruct.library.modifiers.ModifierEntry;
import slimeknights.tconstruct.library.modifiers.TinkerHooks;
import slimeknights.tconstruct.library.modifiers.hook.KeybindInteractModifierHook;
import slimeknights.tconstruct.library.modifiers.hook.interaction.GeneralInteractionModifierHook;
import slimeknights.tconstruct.library.modifiers.hook.interaction.InteractionSource;
import slimeknights.tconstruct.library.modifiers.impl.InventoryModifier;
import slimeknights.tconstruct.library.modifiers.util.ModifierHookMap.Builder;
import slimeknights.tconstruct.library.tools.capability.ToolInventoryCapability;
import slimeknights.tconstruct.library.tools.nbt.IToolStackView;

public class InventoryMenuModifier extends InventoryModifier implements KeybindInteractModifierHook {
public class InventoryMenuModifier extends InventoryModifier implements KeybindInteractModifierHook, GeneralInteractionModifierHook {
/** Loader instance */
public static final GenericIntSerializer<InventoryMenuModifier> LOADER = new GenericIntSerializer<>("size", InventoryMenuModifier::new, t -> t.slotsPerLevel);

Expand All @@ -37,10 +41,19 @@ public boolean startInteract(IToolStackView tool, ModifierEntry modifier, Player
return ToolInventoryCapability.tryOpenContainer(player.getItemBySlot(slot), tool, player, slot).consumesAction();
}

@Override
public InteractionResult onToolUse(IToolStackView tool, ModifierEntry modifier, Player player, InteractionHand hand, InteractionSource source) {
if (player.isCrouching()) {
EquipmentSlot slot = source.getSlot(hand);
return ToolInventoryCapability.tryOpenContainer(player.getItemBySlot(slot), tool, player, slot);
}
return InteractionResult.PASS;
}

@Override
protected void registerHooks(Builder hookBuilder) {
super.registerHooks(hookBuilder);
hookBuilder.addHook(this, TinkerHooks.ARMOR_INTERACT);
hookBuilder.addHook(this, TinkerHooks.ARMOR_INTERACT, TinkerHooks.GENERAL_INTERACT);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import net.minecraft.sounds.SoundSource;
import net.minecraft.stats.Stats;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.InteractionResultHolder;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
Expand All @@ -25,7 +24,6 @@
import slimeknights.tconstruct.library.modifiers.hook.ConditionalStatModifierHook;
import slimeknights.tconstruct.library.tools.capability.EntityModifierCapability;
import slimeknights.tconstruct.library.tools.capability.PersistentDataCapability;
import slimeknights.tconstruct.library.tools.capability.ToolInventoryCapability;
import slimeknights.tconstruct.library.tools.definition.ToolDefinition;
import slimeknights.tconstruct.library.tools.helper.ToolBuildHandler;
import slimeknights.tconstruct.library.tools.helper.ToolDamageUtil;
Expand All @@ -34,7 +32,6 @@
import slimeknights.tconstruct.library.tools.nbt.NamespacedNBT;
import slimeknights.tconstruct.library.tools.nbt.ToolStack;
import slimeknights.tconstruct.library.tools.stat.ToolStats;
import slimeknights.tconstruct.library.utils.Util;
import slimeknights.tconstruct.tools.data.material.MaterialIds;

import java.util.function.Predicate;
Expand Down Expand Up @@ -71,12 +68,6 @@ public InteractionResultHolder<ItemStack> use(Level level, Player player, Intera

// TODO: move this to left click later once left click hooks are implemented
ToolStack tool = ToolStack.from(bow);
if (player.isCrouching()) {
InteractionResult result = ToolInventoryCapability.tryOpenContainer(bow, tool, player, Util.getSlotType(hand));
if (result.consumesAction()) {
return new InteractionResultHolder<>(result, bow);
}
}

// no need to ask the modifiers for ammo if we have it in the inventory, as there is no way for a modifier to say not to use ammo if its present
// inventory search is probably a bit faster on average than modifier search as its already parsed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.material.Material;
import net.minecraftforge.common.ToolAction;
import slimeknights.tconstruct.library.modifiers.ModifierEntry;
import slimeknights.tconstruct.library.modifiers.TinkerHooks;
import slimeknights.tconstruct.library.modifiers.hook.interaction.BlockInteractionModifierHook;
import slimeknights.tconstruct.library.modifiers.hook.interaction.InteractionSource;
import slimeknights.tconstruct.library.modifiers.impl.InteractionModifier;
import slimeknights.tconstruct.library.modifiers.util.ModifierHookMap.Builder;
import slimeknights.tconstruct.library.tools.definition.aoe.IAreaOfEffectIterator;
import slimeknights.tconstruct.library.tools.helper.ToolDamageUtil;
import slimeknights.tconstruct.library.tools.nbt.IToolStackView;
Expand All @@ -25,7 +30,7 @@
import java.util.Iterator;

@RequiredArgsConstructor
public class BlockTransformModifier extends InteractionModifier.NoLevels {
public class BlockTransformModifier extends InteractionModifier.NoLevels implements BlockInteractionModifierHook {
@Getter
private final int priority;
private final ToolAction action;
Expand All @@ -37,6 +42,12 @@ public BlockTransformModifier(int priority, ToolAction action, SoundEvent sound,
this(priority, action, sound, requireGround, -1);
}

@Override
protected void registerHooks(Builder hookBuilder) {
super.registerHooks(hookBuilder);
hookBuilder.addHook(this, TinkerHooks.BLOCK_INTERACT);
}

@Override
public boolean shouldDisplay(boolean advanced) {
return priority > Short.MIN_VALUE;
Expand All @@ -48,7 +59,7 @@ public boolean canPerformAction(IToolStackView tool, int level, ToolAction toolA
}

@Override
public InteractionResult afterBlockUse(IToolStackView tool, int level, UseOnContext context, EquipmentSlot slotType) {
public InteractionResult afterBlockUse(IToolStackView tool, ModifierEntry modifier, UseOnContext context, InteractionSource source) {
// tool must not be broken
if (tool.isBroken()) {
return InteractionResult.PASS;
Expand All @@ -72,6 +83,7 @@ public InteractionResult afterBlockUse(IToolStackView tool, int level, UseOnCont
boolean didTransform = transform(context, original, true);

// if we made a successful transform, client can stop early
EquipmentSlot slotType = source.getSlot(context.getHand());
if (didTransform) {
if (world.isClientSide) {
return InteractionResult.SUCCESS;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,13 @@
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraft.world.level.gameevent.GameEvent;
import net.minecraftforge.common.ToolAction;
import slimeknights.tconstruct.library.modifiers.ModifierEntry;
import slimeknights.tconstruct.library.modifiers.TinkerHooks;
import slimeknights.tconstruct.library.modifiers.hook.interaction.BlockInteractionModifierHook;
import slimeknights.tconstruct.library.modifiers.hook.interaction.EntityInteractionModifierHook;
import slimeknights.tconstruct.library.modifiers.hook.interaction.InteractionSource;
import slimeknights.tconstruct.library.modifiers.impl.InteractionModifier;
import slimeknights.tconstruct.library.modifiers.util.ModifierHookMap.Builder;
import slimeknights.tconstruct.library.tools.definition.aoe.CircleAOEIterator;
import slimeknights.tconstruct.library.tools.definition.aoe.IAreaOfEffectIterator;
import slimeknights.tconstruct.library.tools.helper.ToolDamageUtil;
Expand All @@ -40,13 +46,19 @@
* Modifier that starts a fire at the given position
*/
@RequiredArgsConstructor
public class FirestarterModifier extends InteractionModifier.NoLevels {
public class FirestarterModifier extends InteractionModifier.NoLevels implements EntityInteractionModifierHook, BlockInteractionModifierHook {
/** Compat with mods adding custom campfires */
private static final ToolAction LIGHT_CAMPFIRE = ToolAction.get("light_campfire");

@Getter
private final int priority;

@Override
protected void registerHooks(Builder hookBuilder) {
super.registerHooks(hookBuilder);
hookBuilder.addHook(this, TinkerHooks.ENTITY_INTERACT, TinkerHooks.BLOCK_INTERACT);
}

@Override
public boolean shouldDisplay(boolean advanced) {
return priority > Short.MIN_VALUE;
Expand All @@ -58,12 +70,12 @@ public boolean canPerformAction(IToolStackView tool, int level, ToolAction toolA
}

@Override
public InteractionResult afterEntityUse(IToolStackView tool, int level, Player player, LivingEntity target, InteractionHand hand, EquipmentSlot slotType) {
public InteractionResult afterEntityUse(IToolStackView tool, ModifierEntry modifier, Player player, LivingEntity target, InteractionHand hand, InteractionSource source) {
if (target instanceof Creeper creeper) {
player.level.playSound(player, creeper.getX(), creeper.getY(), creeper.getZ(), SoundEvents.FLINTANDSTEEL_USE, creeper.getSoundSource(), 1.0F, RANDOM.nextFloat() * 0.4F + 0.8F);
if (!player.level.isClientSide) {
creeper.ignite();
ToolDamageUtil.damageAnimated(tool, 1, player, slotType);
ToolDamageUtil.damageAnimated(tool, 1, player, source.getSlot(hand));
}
return InteractionResult.sidedSuccess(player.level.isClientSide);
}
Expand Down Expand Up @@ -98,18 +110,18 @@ private static boolean ignite(IToolStackView tool, Level world, BlockPos pos, Bl
}

@Override
public InteractionResult beforeBlockUse(IToolStackView tool, int level, UseOnContext context, EquipmentSlot slotType) {
public InteractionResult beforeBlockUse(IToolStackView tool, ModifierEntry modifier, UseOnContext context, InteractionSource source) {
if (tool.isBroken()) {
return InteractionResult.PASS;
}
if (context.getLevel().getBlockState(context.getClickedPos()).is(BlockTags.CANDLE_CAKES)) {
return afterBlockUse(tool, level, context, slotType);
return afterBlockUse(tool, modifier, context, source);
}
return InteractionResult.PASS;
}

@Override
public InteractionResult afterBlockUse(IToolStackView tool, int level, UseOnContext context, EquipmentSlot slotType) {
public InteractionResult afterBlockUse(IToolStackView tool, ModifierEntry modifier, UseOnContext context, InteractionSource source) {
if (tool.isBroken()) {
return InteractionResult.PASS;
}
Expand Down Expand Up @@ -138,6 +150,7 @@ public InteractionResult afterBlockUse(IToolStackView tool, int level, UseOnCont
// first burn the center, unless we already know its fire
boolean didIgnite = false;
ItemStack stack = context.getItemInHand();
EquipmentSlot slotType = source.getSlot(context.getHand());
if (!targetingFire) {
didIgnite = ignite(tool, world, pos, state, sideHit, horizontalFacing, player);
if (didIgnite && ToolDamageUtil.damage(tool, 1, player, stack)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.Level;
Expand All @@ -27,7 +25,10 @@
import slimeknights.tconstruct.library.events.TinkerToolEvent.ToolHarvestEvent;
import slimeknights.tconstruct.library.modifiers.ModifierEntry;
import slimeknights.tconstruct.library.modifiers.TinkerHooks;
import slimeknights.tconstruct.library.modifiers.hook.interaction.BlockInteractionModifierHook;
import slimeknights.tconstruct.library.modifiers.hook.interaction.InteractionSource;
import slimeknights.tconstruct.library.modifiers.impl.InteractionModifier;
import slimeknights.tconstruct.library.modifiers.util.ModifierHookMap.Builder;
import slimeknights.tconstruct.library.tools.definition.aoe.IAreaOfEffectIterator;
import slimeknights.tconstruct.library.tools.helper.ToolDamageUtil;
import slimeknights.tconstruct.library.tools.nbt.IToolStackView;
Expand All @@ -38,10 +39,16 @@
import java.util.List;

@RequiredArgsConstructor
public class HarvestAbilityModifier extends InteractionModifier.NoLevels {
public class HarvestAbilityModifier extends InteractionModifier.NoLevels implements BlockInteractionModifierHook {
@Getter
private final int priority;

@Override
protected void registerHooks(Builder hookBuilder) {
super.registerHooks(hookBuilder);
hookBuilder.addHook(this, TinkerHooks.BLOCK_INTERACT);
}

@Override
public boolean shouldDisplay(boolean advanced) {
return priority > Short.MIN_VALUE;
Expand Down Expand Up @@ -183,11 +190,11 @@ private static boolean harvestCrop(ItemStack stack, ServerLevel world, BlockStat
* @param world Level instance
* @param state State to harvest
* @param pos Position to harvest
* @param slotType Slot used to harvest
* @param source Source of the interaction
* @return True if harvested
*/
@SuppressWarnings("deprecation")
private static boolean harvest(UseOnContext context, IToolStackView tool, ServerLevel world, BlockState state, BlockPos pos, EquipmentSlot slotType) {
private static boolean harvest(UseOnContext context, IToolStackView tool, ServerLevel world, BlockState state, BlockPos pos, InteractionSource source) {
Player player = context.getPlayer();
// first, check main harvestable tag
Holder<Block> holder = state.getBlock().builtInRegistryHolder();
Expand All @@ -196,7 +203,7 @@ private static boolean harvest(UseOnContext context, IToolStackView tool, Server
}
// try harvest event
boolean didHarvest = false;
Result result = new ToolHarvestEvent(tool, context, world, state, pos, slotType).fire();
Result result = new ToolHarvestEvent(tool, context, world, state, pos, source).fire();
if (result != Result.DEFAULT) {
didHarvest = result == Result.ALLOW;

Expand Down Expand Up @@ -224,7 +231,7 @@ private static boolean harvest(UseOnContext context, IToolStackView tool, Server
}

@Override
public InteractionResult beforeBlockUse(IToolStackView tool, int level, UseOnContext context, EquipmentSlot slotType) {
public InteractionResult beforeBlockUse(IToolStackView tool, ModifierEntry modifier, UseOnContext context, InteractionSource source) {
if (tool.isBroken()) {
return InteractionResult.PASS;
}
Expand All @@ -247,17 +254,16 @@ public InteractionResult beforeBlockUse(IToolStackView tool, int level, UseOnCon
boolean didHarvest = false;
boolean broken = false;
ItemStack stack = context.getItemInHand();
if (harvest(context, tool, server, state, pos, slotType)) {
if (harvest(context, tool, server, state, pos, source)) {
didHarvest = true;
broken = survival && ToolDamageUtil.damage(tool, 1, player, stack);
}

// if we have a player and harvest logic, try doing AOE harvest
Item item = stack.getItem();
if (!broken && player != null) {
for (BlockPos newPos : tool.getDefinition().getData().getAOE().getBlocks(tool, stack, player, state, world, pos, context.getClickedFace(), IAreaOfEffectIterator.AOEMatchType.TRANSFORM)) {
// try harvesting the crop, if successful and survival, damage the tool
if (harvest(context, tool, server, world.getBlockState(newPos), newPos, slotType)) {
if (harvest(context, tool, server, world.getBlockState(newPos), newPos, source)) {
didHarvest = true;
if (survival && ToolDamageUtil.damage(tool, 1, player, stack)) {
broken = true;
Expand Down

0 comments on commit f00755a

Please sign in to comment.