Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow collecting taters while not holding a tater box #150

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 22 additions & 5 deletions src/main/java/xyz/nucleoid/extras/lobby/NEItems.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import eu.pb4.polymer.core.api.block.PolymerHeadBlock;
import eu.pb4.polymer.core.api.item.PolymerItemGroupUtils;
import net.fabricmc.fabric.api.event.player.UseBlockCallback;
import net.fabricmc.fabric.api.event.player.UseEntityCallback;
import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup;
import net.fabricmc.fabric.api.networking.v1.PacketSender;
Expand All @@ -20,6 +21,7 @@
import net.minecraft.text.Text;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.EntityHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
Expand Down Expand Up @@ -795,6 +797,7 @@ public static void register() {

ServerPlayConnectionEvents.JOIN.register(NEItems::onPlayerJoin);

UseBlockCallback.EVENT.register(NEItems::onUseBlock);
UseEntityCallback.EVENT.register(NEItems::onUseEntity);
}

Expand Down Expand Up @@ -828,15 +831,29 @@ private static void onPlayerJoin(ServerPlayNetworkHandler handler, PacketSender
});
}

private static ActionResult onUseBlock(PlayerEntity player, World world, Hand hand, BlockHitResult hitResult) {
if (!player.getWorld().isClient() && hitResult != null && hand == Hand.MAIN_HAND) {
ItemStack stack = player.getStackInHand(hand);
BlockPos pos = hitResult.getBlockPos();

PlayerLobbyState state = PlayerLobbyState.get(player);
ActionResult result = state.collectTaterFromBlock(world, pos, stack, player);

return result;
}

return ActionResult.PASS;
}

private static ActionResult onUseEntity(PlayerEntity player, World world, Hand hand, Entity entity, EntityHitResult hitResult) {
if (!player.getWorld().isClient() && hitResult != null) {
ItemStack stack = player.getStackInHand(hand);
if (stack.getItem() instanceof TaterBoxItem taterBox) {
Vec3d hitPos = hitResult.getPos().subtract(entity.getPos());
ActionResult result = taterBox.tryAdd(entity, hitPos, stack, player);
Vec3d hitPos = hitResult.getPos().subtract(entity.getPos());

PlayerLobbyState state = PlayerLobbyState.get(player);
ActionResult result = state.collectTaterFromEntity(entity, hitPos, stack, player);

return result.isAccepted() ? result : ActionResult.FAIL;
}
return result;
}

return ActionResult.PASS;
Expand Down
96 changes: 96 additions & 0 deletions src/main/java/xyz/nucleoid/extras/lobby/PlayerLobbyState.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,26 @@
import eu.pb4.playerdata.api.PlayerDataApi;
import eu.pb4.playerdata.api.storage.JsonDataStorage;
import eu.pb4.playerdata.api.storage.PlayerDataStorage;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.decoration.ArmorStandEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemStack;
import net.minecraft.registry.Registries;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Formatting;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import xyz.nucleoid.extras.lobby.block.tater.TinyPotatoBlock;
import xyz.nucleoid.extras.lobby.item.TaterBoxItem;
import xyz.nucleoid.extras.mixin.lobby.ArmorStandEntityAccessor;

import java.util.HashSet;
import java.util.Set;
Expand All @@ -15,6 +32,85 @@ public class PlayerLobbyState {
public static final PlayerDataStorage<PlayerLobbyState> STORAGE = new JsonDataStorage<>("nucleoid_extras", PlayerLobbyState.class);
public final Set<TinyPotatoBlock> collectedTaters = new HashSet<>();

public ActionResult collectTaterFromBlock(World world, BlockPos pos, ItemStack stack, PlayerEntity player) {
BlockState state = world.getBlockState(pos);
Block block = state.getBlock();

ActionResult result = this.collectTater(block, stack, player);

if (isFickle(result, block, player)) {
world.breakBlock(pos, false);
}

return result;
}

public ActionResult collectTaterFromEntity(Entity entity, Vec3d hitPos, ItemStack stack, PlayerEntity player) {
if (entity instanceof ArmorStandEntity armorStand) {
EquipmentSlot slot = ((ArmorStandEntityAccessor) (Object) armorStand).callSlotFromPosition(hitPos);
return this.collectTaterFromSlot(armorStand.getEquippedStack(slot), stack, player);
} else if (entity instanceof PlayerEntity targetPlayer) {
ItemStack targetStack = targetPlayer.getEquippedStack(EquipmentSlot.HEAD);

if (targetStack.getItem() instanceof TaterBoxItem) {
Block targetTater = TaterBoxItem.getSelectedTater(targetStack);

if (targetTater != null && targetTater.getDefaultState().isIn(TaterBoxItem.VIRAL_TATERS)) {
return this.collectTater(targetTater, stack, player);
}
}
}

return ActionResult.PASS;
}

private ActionResult collectTaterFromSlot(ItemStack slotStack, ItemStack stack, PlayerEntity player) {
if (!slotStack.isEmpty() && slotStack.getItem() instanceof BlockItem slotItem) {
Block block = slotItem.getBlock();
ActionResult result = this.collectTater(block, stack, player);

if (isFickle(result, block, player)) {
slotStack.setCount(0);
}

return result;
}

return ActionResult.PASS;
}

private ActionResult collectTater(Block block, ItemStack stack, PlayerEntity player) {
if (!(block instanceof TinyPotatoBlock tater)) return ActionResult.PASS;

if (stack.getItem() instanceof TaterBoxItem) {
stack.getOrCreateNbt().putUuid(TaterBoxItem.OWNER_KEY, player.getUuid());
}

boolean alreadyAdded = this.collectedTaters.contains(tater);
Text message;

if (alreadyAdded) {
message = Text.translatable("text.nucleoid_extras.tater_box.already_added", block.getName()).formatted(Formatting.RED);
} else {
this.collectedTaters.add(tater);

message = Text.translatable("text.nucleoid_extras.tater_box.added", block.getName());
}

player.sendMessage(message, true);
triggerCollectCriterion((ServerPlayerEntity) player, Registries.BLOCK.getId(tater), this.collectedTaters.size());

return alreadyAdded ? ActionResult.FAIL : ActionResult.SUCCESS;
}

private static void triggerCollectCriterion(ServerPlayerEntity player, Identifier taterId, int count) {
NECriteria.TATER_COLLECTED.trigger(player, taterId, count);
}

private static boolean isFickle(ActionResult result, Block block, PlayerEntity player) {
return result.isAccepted() && block instanceof TinyPotatoBlock tater && tater.isFickle() && !player.isCreative();
}

public static PlayerLobbyState get(PlayerEntity player) {
if (!(player instanceof ServerPlayerEntity serverPlayer)) {
return new PlayerLobbyState();
Expand Down
123 changes: 14 additions & 109 deletions src/main/java/xyz/nucleoid/extras/lobby/item/TaterBoxItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@
import eu.pb4.polymer.core.api.utils.PolymerUtils;
import eu.pb4.sgui.api.elements.GuiElementInterface;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.client.item.TooltipContext;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.decoration.ArmorStandEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.*;
import net.minecraft.nbt.NbtCompound;
Expand All @@ -22,35 +18,28 @@
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.util.*;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.RaycastContext;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;
import xyz.nucleoid.extras.NucleoidExtras;
import xyz.nucleoid.extras.lobby.NECriteria;
import xyz.nucleoid.extras.lobby.NEItems;
import xyz.nucleoid.extras.lobby.PlayerLobbyState;
import xyz.nucleoid.extras.lobby.block.tater.CubicPotatoBlock;
import xyz.nucleoid.extras.lobby.block.tater.TinyPotatoBlock;
import xyz.nucleoid.extras.lobby.gui.TaterBoxGui;
import xyz.nucleoid.extras.mixin.lobby.ArmorStandEntityAccessor;

import java.util.*;

public class TaterBoxItem extends ArmorItem implements PolymerItem {
private static final Text NOT_OWNER_MESSAGE = Text.translatable("text.nucleoid_extras.tater_box.not_owner").formatted(Formatting.RED);
public static final Text NONE_TEXT = Text.translatable("text.nucleoid_extras.tater_box.none");

private static final String OWNER_KEY = "Owner";
public static final String OWNER_KEY = "Owner";
private static final String LEGACY_TATERS_KEY = "Taters";
private static final String SELECTED_TATER_KEY = "SelectedTater";
private static final int COLOR = 0xCEADAA;

private static final Identifier VIRAL_TATERS_ID = NucleoidExtras.identifier("viral_taters");
private static final TagKey<Block> VIRAL_TATERS = TagKey.of(RegistryKeys.BLOCK, VIRAL_TATERS_ID);
public static final TagKey<Block> VIRAL_TATERS = TagKey.of(RegistryKeys.BLOCK, VIRAL_TATERS_ID);

public TaterBoxItem(Settings settings) {
super(ArmorMaterials.LEATHER, ArmorItem.Type.HELMET, settings);
Expand Down Expand Up @@ -78,7 +67,6 @@ private MutableText getTitle(ServerPlayerEntity player) {
@Override
public TypedActionResult<ItemStack> use(World world, PlayerEntity user, Hand hand) {
ItemStack stack = user.getStackInHand(hand);
TypedActionResult<ItemStack> result = TypedActionResult.success(stack, world.isClient());

if (!world.isClient()) {
if (stack.hasNbt() && stack.getNbt().contains(LEGACY_TATERS_KEY)) {
Expand All @@ -95,29 +83,24 @@ public TypedActionResult<ItemStack> use(World world, PlayerEntity user, Hand han
user.sendMessage(Text.translatable("text.nucleoid_extras.tater_box.updated"));
}

BlockHitResult hit = Item.raycast(world, user, RaycastContext.FluidHandling.NONE);
if (hit.getType() == HitResult.Type.BLOCK) {
result = new TypedActionResult<>(this.tryAdd(world, hit.getBlockPos(), stack, user), stack);
} else {
var state = PlayerLobbyState.get(user);
List<GuiElementInterface> taters = new ArrayList<>();
var state = PlayerLobbyState.get(user);
List<GuiElementInterface> taters = new ArrayList<>();

taters.add(createGuiElement(stack, user, hand, Items.BARRIER, NONE_TEXT, null, true));
taters.add(createGuiElement(stack, user, hand, Items.BARRIER, NONE_TEXT, null, true));

for (var tater : TinyPotatoBlock.TATERS) {
boolean found = state.collectedTaters.contains(tater);
for (var tater : TinyPotatoBlock.TATERS) {
boolean found = state.collectedTaters.contains(tater);

taters.add(createGuiElement(stack, user, hand, tater, tater.getName(), Registries.BLOCK.getId(tater), found));
}

var ui = TaterBoxGui.of((ServerPlayerEntity) user, taters);
ui.setHideUnfound(true);
ui.setTitle(this.getTitle((ServerPlayerEntity) user));
ui.open();
taters.add(createGuiElement(stack, user, hand, tater, tater.getName(), Registries.BLOCK.getId(tater), found));
}

var ui = TaterBoxGui.of((ServerPlayerEntity) user, taters);
ui.setHideUnfound(true);
ui.setTitle(this.getTitle((ServerPlayerEntity) user));
ui.open();
}

return result;
return TypedActionResult.success(stack, world.isClient());
}

private TaterBoxGui.TaterGuiElement createGuiElement(ItemStack stack, PlayerEntity user, Hand hand, ItemConvertible icon, Text text, Identifier taterId, boolean found) {
Expand All @@ -136,76 +119,6 @@ private TaterBoxGui.TaterGuiElement createGuiElement(ItemStack stack, PlayerEnti
return guiElementBuilder.build();
}

private ActionResult tryAdd(World world, BlockPos pos, ItemStack stack, PlayerEntity player) {
BlockState state = world.getBlockState(pos);
Block block = state.getBlock();

ActionResult result = this.tryAdd(block, stack, player);

if (isFickle(result, block, player)) {
world.breakBlock(pos, false);
}

return result;
}

public ActionResult tryAdd(Entity entity, Vec3d hitPos, ItemStack stack, PlayerEntity player) {
if (entity instanceof ArmorStandEntity armorStand) {
EquipmentSlot slot = ((ArmorStandEntityAccessor) (Object) armorStand).callSlotFromPosition(hitPos);
return this.tryAdd(armorStand.getEquippedStack(slot), stack, player);
} else if (entity instanceof PlayerEntity targetPlayer) {
ItemStack targetStack = targetPlayer.getEquippedStack(EquipmentSlot.HEAD);

if (targetStack.getItem() instanceof TaterBoxItem) {
Block targetTater = TaterBoxItem.getSelectedTater(targetStack);

if (targetTater != null && targetTater.getDefaultState().isIn(VIRAL_TATERS)) {
return this.tryAdd(targetTater, stack, player);
}
}
}

return ActionResult.PASS;
}

private ActionResult tryAdd(ItemStack slotStack, ItemStack stack, PlayerEntity player) {
if (!slotStack.isEmpty() && slotStack.getItem() instanceof BlockItem slotItem) {
Block block = slotItem.getBlock();
ActionResult result = this.tryAdd(block, stack, player);

if (isFickle(result, block, player)) {
slotStack.setCount(0);
}

return result;
}

return ActionResult.PASS;
}

private ActionResult tryAdd(Block block, ItemStack stack, PlayerEntity player) {
if (!(block instanceof TinyPotatoBlock tater)) return ActionResult.PASS;
stack.getOrCreateNbt().putUuid(OWNER_KEY, player.getUuid());

var state = PlayerLobbyState.get(player);

boolean alreadyAdded = state.collectedTaters.contains(tater);
Text message;

if (alreadyAdded) {
message = Text.translatable("text.nucleoid_extras.tater_box.already_added", block.getName()).formatted(Formatting.RED);
} else {
state.collectedTaters.add(tater);

message = Text.translatable("text.nucleoid_extras.tater_box.added", block.getName());
}

player.sendMessage(message, true);
TaterBoxItem.triggerCriterion((ServerPlayerEntity) player, Registries.BLOCK.getId(tater), state.collectedTaters.size());

return alreadyAdded ? ActionResult.FAIL : ActionResult.SUCCESS;
}

@Override
public Item getPolymerItem(ItemStack itemStack, @Nullable ServerPlayerEntity player) {
if (TaterBoxItem.getSelectedTater(itemStack) != null) {
Expand Down Expand Up @@ -281,10 +194,6 @@ public static Block getSelectedTater(ItemStack stack) {
return Registries.BLOCK.get(id);
}

private static boolean isFickle(ActionResult result, Block block, PlayerEntity player) {
return result.isAccepted() && block instanceof TinyPotatoBlock tater && tater.isFickle() && !player.isCreative();
}

public static void setSelectedTater(ItemStack stack, @Nullable Identifier selectedTaterId) {
NbtCompound tag = stack.getOrCreateNbt();
if(selectedTaterId == null) {
Expand All @@ -294,10 +203,6 @@ public static void setSelectedTater(ItemStack stack, @Nullable Identifier select
}
}

public static void triggerCriterion(ServerPlayerEntity player, Identifier taterId, int count) {
NECriteria.TATER_COLLECTED.trigger(player, taterId, count);
}

public static void addToItemGroup(ItemGroup.Entries entries) {
ItemStack fullStack = new ItemStack(NEItems.TATER_BOX);

Expand Down
Loading