Skip to content

Commit

Permalink
🔨 Fix #6
Browse files Browse the repository at this point in the history
  • Loading branch information
Hugman76 committed Mar 15, 2023
1 parent 40ee71a commit 315cfc4
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 35 deletions.
22 changes: 21 additions & 1 deletion src/main/java/fr/hugman/build_rush/event/UseEvents.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUsageContext;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
Expand All @@ -10,7 +12,7 @@
import xyz.nucleoid.stimuli.event.StimulusEvent;

public class UseEvents {
public static final StimulusEvent<UseBlockEvent> USE_BLOCK = StimulusEvent.create(UseBlockEvent.class, ctx -> (state, world, pos, player, hand, hit) -> {
public static final StimulusEvent<UseBlockEvent> BLOCK = StimulusEvent.create(UseBlockEvent.class, ctx -> (state, world, pos, player, hand, hit) -> {
try {
for(var listener : ctx.getListeners()) {
var result = listener.onBlockUsed(state, world, pos, player, hand, hit);
Expand All @@ -24,7 +26,25 @@ public class UseEvents {
return ActionResult.PASS;
});

public static final StimulusEvent<UseItemOnBlockEvent> ITEM_ON_BLOCK = StimulusEvent.create(UseItemOnBlockEvent.class, ctx -> (stack, context) -> {
try {
for(var listener : ctx.getListeners()) {
var result = listener.onItemUsedOnBlock(stack, context);
if(result != ActionResult.PASS) {
return result;
}
}
} catch(Throwable t) {
ctx.handleException(t);
}
return ActionResult.PASS;
});

public interface UseBlockEvent {
ActionResult onBlockUsed(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit);
}

public interface UseItemOnBlockEvent {
ActionResult onItemUsedOnBlock(ItemStack stack, ItemUsageContext context);
}
}
65 changes: 38 additions & 27 deletions src/main/java/fr/hugman/build_rush/game/state/BRActive.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
import net.minecraft.entity.boss.BossBar;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUsageContext;
import net.minecraft.item.Items;
import net.minecraft.particle.ParticleTypes;
import net.minecraft.server.network.ServerPlayerEntity;
Expand Down Expand Up @@ -52,7 +51,6 @@
import xyz.nucleoid.stimuli.event.block.FluidPlaceEvent;
import xyz.nucleoid.stimuli.event.player.PlayerDamageEvent;
import xyz.nucleoid.stimuli.event.player.PlayerDeathEvent;
import xyz.nucleoid.stimuli.event.world.FluidFlowEvent;

import java.util.ArrayList;
import java.util.HashMap;
Expand All @@ -79,7 +77,7 @@ public class BRActive {
private long closeTick;
private final BRRound round;
public final Sidebar globalSidebar = new Sidebar(Sidebar.Priority.MEDIUM);
private boolean canBuild;
private boolean canInteractWithWorld;

public BRActive(BRConfig config, GameSpace space, ServerWorld world, BlockBounds center, BlockBounds centerPlot, StructureTemplate platform, StructureTemplate plotGround, List<PlotStructure> plotStructures) {
this.config = config;
Expand All @@ -99,7 +97,7 @@ public BRActive(BRConfig config, GameSpace space, ServerWorld world, BlockBounds
this.round = new BRRound(this, 10, 40);
this.tick = 0;
this.closeTick = Long.MAX_VALUE;
this.canBuild = false;
this.canInteractWithWorld = false;
}

public GameResult transferActivity() {
Expand Down Expand Up @@ -135,11 +133,13 @@ public GameResult transferActivity() {
this.resetPlayer(player, true);
return ActionResult.FAIL;
});
activity.listen(BlockPlaceEvent.BEFORE, this::placeBlock);
activity.listen(FluidPlaceEvent.EVENT, this::placeFluid);
activity.listen(BlockPlaceEvent.BEFORE, (player, world1, pos, state, context) -> this.interactWithWorld(player, pos));
activity.listen(FluidPlaceEvent.EVENT, (world1, pos, player, hitResult) -> this.interactWithWorld(player, pos));
activity.listen(BlockPunchEvent.EVENT, this::punchBlock);
activity.listen(WorldBlockBreakEvent.EVENT, this::onBlockBroken);
activity.listen(UseEvents.USE_BLOCK, this::onBlockUsed);
activity.listen(UseEvents.BLOCK, this::onBlockUsed);
activity.listen(UseEvents.ITEM_ON_BLOCK, (stack, context) ->
this.interactWithWorld((ServerPlayerEntity) context.getPlayer(), context.getBlockPos().add(context.getSide().getVector())));
});

return GameResult.ok();
Expand Down Expand Up @@ -252,7 +252,7 @@ private void onClose(GameCloseReason gameCloseReason) {
}

public void canBuild(boolean canBuild) {
this.canBuild = canBuild;
this.canInteractWithWorld = canBuild;
}

public void eliminateLast() {
Expand Down Expand Up @@ -401,34 +401,45 @@ public void give(PlayerEntity player, ItemStack stack) {
/* LISTENERS */
/*=============*/

private ActionResult placeBlock(ServerPlayerEntity player, ServerWorld world, BlockPos pos, BlockState state, ItemUsageContext itemUsageContext) {
private ActionResult interactWithWorld(@Nullable ServerPlayerEntity player, BlockPos pos) {
return canInteractWithWorld(player, pos) ? ActionResult.SUCCESS : ActionResult.FAIL;
}

private boolean canInteractWithWorld(@Nullable ServerPlayerEntity player, BlockPos pos) {
if(!this.canInteractWithWorld) {
BuildRush.debug("interactWithWorld: cannot build");
return false;
}
if(player == null) {
BuildRush.debug("interactWithWorld: player is null");
return false;
}
if(this.isClosing()) {
BuildRush.debug("interactWithWorld: game is closing");
return false;
}
var data = this.playerDataMap.get(player.getUuid());
if(data == null || data.eliminated || this.isClosing()) {
return ActionResult.FAIL;
if(data == null) {
BuildRush.debug("interactWithWorld: player has no data");
return false;
}
if(this.canBuild && data.plot.contains(pos)) {
return ActionResult.SUCCESS;
if(data.eliminated) {
BuildRush.debug("interactWithWorld: player is eliminated");
return false;
}
return ActionResult.FAIL;
}

private ActionResult placeFluid(ServerWorld world, BlockPos pos, @Nullable ServerPlayerEntity player, @Nullable BlockHitResult blockHitResult) {
if(player == null || this.isClosing()) {
return ActionResult.FAIL;
if(!data.plot.contains(pos)) {
BuildRush.debug("interactWithWorld: block outside player's plot");
return false;
}
return placeBlock(player, world, pos, world.getBlockState(pos), null);
return true;
}

private ActionResult onBlockUsed(BlockState state, World world, BlockPos blockPos, PlayerEntity playerEntity, Hand hand, BlockHitResult blockHitResult) {
return ActionResult.FAIL;
}

private ActionResult punchBlock(ServerPlayerEntity player, Direction direction, BlockPos pos) {
var data = this.playerDataMap.get(player.getUuid());
if(data == null || data.eliminated || this.isClosing()) {
return ActionResult.FAIL;
}
if(this.canBuild && data.plot.contains(pos)) {
if(canInteractWithWorld(player, pos)) {
/*
This currently doesn't work very well, so I'm disabling it for now
If you hold the click it won't break the second block if you're still holding the click
Expand All @@ -443,7 +454,7 @@ private ActionResult punchBlock(ServerPlayerEntity player, Direction direction,
this.world.setBlockState(pos, Blocks.AIR.getDefaultState());
this.world.spawnParticles(ParticleTypes.CRIT, center.getX(), center.getY(), center.getZ(), 5, 0.1D, 0.1D, 0.1D, 0.03D);
this.world.playSound(null, pos, state.getSoundGroup().getBreakSound(), SoundCategory.BLOCKS, 1.0f, 0.8f);
data.breakingCooldown = BRPlayerData.BREAKING_COOLDOWN;
this.playerDataMap.get(player.getUuid()).breakingCooldown = BRPlayerData.BREAKING_COOLDOWN;
return ActionResult.SUCCESS;
}
return ActionResult.FAIL;
Expand All @@ -462,7 +473,7 @@ private ActionResult onBlockBroken(BlockPos pos, boolean drops, @Nullable Entity
if(data == null || data.eliminated || this.isClosing()) {
return ActionResult.FAIL;
}
if(this.canBuild) {
if(this.canInteractWithWorld) {
var state = this.world.getBlockState(pos);
var center = pos.toCenterPos();
var player = this.space.getPlayers().getEntity(uuid);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

import fr.hugman.build_rush.event.UseEvents;
import net.minecraft.block.AbstractBlock;
import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.network.packet.s2c.play.ScreenHandlerSlotUpdateS2CPacket;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
Expand All @@ -16,16 +16,22 @@
import xyz.nucleoid.stimuli.Stimuli;

@Mixin(AbstractBlock.AbstractBlockState.class)
public class AbstractBlockMixin {
public class AbstractBlockStateMixin {
@Inject(method = "onUse", at = @At("HEAD"), cancellable = true)
private void onUse(World world, PlayerEntity player, Hand hand, BlockHitResult hit, CallbackInfoReturnable<ActionResult> cir) {
if(!world.isClient()) {
var events = Stimuli.select();
try(var invokers = events.forEntityAt(player, hit.getBlockPos())) {
var state = world.getBlockState(hit.getBlockPos());
var result = invokers.get(UseEvents.USE_BLOCK).onBlockUsed(state, world, hit.getBlockPos(), player, hand, hit);
if(result != ActionResult.PASS) {
cir.setReturnValue(result);
var result = invokers.get(UseEvents.BLOCK).onBlockUsed(state, world, hit.getBlockPos(), player, hand, hit);

if (result == ActionResult.FAIL) {
// notify the client that this action did not go through
int slot = hand == Hand.MAIN_HAND ? player.getInventory().selectedSlot : 40;
var stack = player.getStackInHand(hand);
((ServerPlayerEntity)player).networkHandler.sendPacket(new ScreenHandlerSlotUpdateS2CPacket(ScreenHandlerSlotUpdateS2CPacket.UPDATE_PLAYER_INVENTORY_SYNC_ID, 0, slot, stack));

cir.setReturnValue(ActionResult.FAIL);
}
}
}
Expand Down
39 changes: 39 additions & 0 deletions src/main/java/fr/hugman/build_rush/mixin/ItemStackMixin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package fr.hugman.build_rush.mixin;

import fr.hugman.build_rush.event.UseEvents;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUsageContext;
import net.minecraft.network.packet.s2c.play.ScreenHandlerSlotUpdateS2CPacket;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import xyz.nucleoid.stimuli.Stimuli;

@Mixin(ItemStack.class)
public class ItemStackMixin {
@Inject(method = "useOnBlock", at = @At(value = "INVOKE", target = "Lnet/minecraft/item/Item;useOnBlock(Lnet/minecraft/item/ItemUsageContext;)Lnet/minecraft/util/ActionResult;"), cancellable = true)
private void useOnBlock(ItemUsageContext context, CallbackInfoReturnable<ActionResult> cir) {
var world = context.getWorld();
if(!context.getWorld().isClient()) {
var events = Stimuli.select();
var player = context.getPlayer();
var pos = context.getBlockPos();
try(var invokers = player == null ? events.at(world,pos) : events.forEntityAt(player, pos)) {
var result = invokers.get(UseEvents.ITEM_ON_BLOCK).onItemUsedOnBlock((ItemStack) (Object) this, context);

if (result == ActionResult.FAIL) {
// notify the client that this action did not go through
int slot = context.getHand() == Hand.MAIN_HAND ? player.getInventory().selectedSlot : 40;
var stack = context.getStack();
((ServerPlayerEntity)player).networkHandler.sendPacket(new ScreenHandlerSlotUpdateS2CPacket(ScreenHandlerSlotUpdateS2CPacket.UPDATE_PLAYER_INVENTORY_SYNC_ID, 0, slot, stack));

cir.setReturnValue(ActionResult.FAIL);
}
}
}
}
}
2 changes: 1 addition & 1 deletion src/main/resources/build_rush.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"minVersion": "0.8",
"package": "fr.hugman.build_rush.mixin",
"compatibilityLevel": "JAVA_17",
"mixins": ["AbstractBlockMixin", "WorldMixin"],
"mixins": ["AbstractBlockStateMixin", "ItemStackMixin", "WorldMixin"],
"injectors": {
"defaultRequire": 1
}
Expand Down

0 comments on commit 315cfc4

Please sign in to comment.