Skip to content

Commit

Permalink
Improvements for free blocks management (#9911)
Browse files Browse the repository at this point in the history
Adds a button in the TH permissions page to obtain a Permission Scepter (which already existed, but was creative-only and nobody knew about it):
image
Changes the free interaction list to display the friendly name of the block (and fix up some size/wrapping issues):
You still have to type the block id if you want to add a block via the GUI.
image
Entering a non-existent block id is now ignored, instead of adding Air.
Makes UI buttons disable properly when you don't have Edit Permissions permission.
The Permission Scepter tooltip shows whether it's in tool or location mode.
image
Holding CTRL when clicking a block with the Permission Scepter now removes that block/location from the list.
Why not SHIFT? Because you'll often also have to hold shift in order to avoid triggering interactive blocks -- and interactive blocks are the whole point.
While holding a Permission Scepter, green boxes will be shown around free interaction blocks/locations.
It shows either blocks or locations depending on the current tool mode.
Locations will be shown colony-wide.
Blocks will only be shown if you're relatively close (for performance reasons).
  • Loading branch information
Raycoms committed Apr 21, 2024
1 parent 532d4a0 commit 9070dc0
Show file tree
Hide file tree
Showing 8 changed files with 155 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,11 @@ public final class WindowConstants
*/
public static final String BUTTON_REMOVE_BLOCK = "removeBlock";

/**
* Button to obtain a permissions scepter.
*/
public static final String BUTTON_BLOCK_TOOL = "blockTool";

/**
* Button to select a block for a replacement.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ public class ToolTranslationConstants
@NonNls
public static final String TOOL_PERMISSION_SCEPTER_SET_MODE = "com.minecolonies.coremod.item.permissionscepter.setmode";
@NonNls
public static final String TOOL_PERMISSION_SCEPTER_MODE = "com.minecolonies.coremod.item.permissionscepter.mode";
@NonNls
public static final String TOOL_PERMISSION_SCEPTER_MODE_BLOCK = "com.minecolonies.coremod.item.permissionscepter.mode.block";
@NonNls
public static final String TOOL_PERMISSION_SCEPTER_MODE_LOCATION = "com.minecolonies.coremod.item.permissionscepter.mode.location";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@
import com.ldtteam.blockui.views.DropDownList;
import com.ldtteam.blockui.views.ScrollingList;
import com.minecolonies.api.colony.permissions.*;
import com.minecolonies.api.items.ModItems;
import com.minecolonies.api.util.BlockPosUtil;
import com.minecolonies.api.util.SoundUtils;
import com.minecolonies.core.colony.buildings.workerbuildings.BuildingTownHall;
import com.minecolonies.core.network.messages.PermissionsMessage;
import com.minecolonies.core.network.messages.server.colony.ChangeFreeToInteractBlockMessage;
import com.minecolonies.core.network.messages.server.colony.building.GiveToolMessage;
import net.minecraft.ChatFormatting;
import net.minecraft.ResourceLocationException;
import net.minecraft.client.Minecraft;
import net.minecraft.client.player.LocalPlayer;
Expand Down Expand Up @@ -117,6 +120,7 @@ public WindowPermissionsPage(final BuildingTownHall.View building)
registerButton(BUTTON_TRIGGER, this::trigger);
registerButton(BUTTON_ADD_BLOCK, this::addBlock);
registerButton(BUTTON_REMOVE_BLOCK, this::removeBlock);
registerButton(BUTTON_BLOCK_TOOL, this::giveBlockTool);
registerButton(BUTTON_ADD_RANK, this::addRank);
registerButton(TOWNHALL_RANK_BUTTON, this::onRankButtonClicked);
registerButton(BUTTON_REMOVE_RANK, this::onRemoveRankButtonClicked);
Expand Down Expand Up @@ -256,14 +260,17 @@ public void onOpened()
final TextField playerNameField = findPaneOfTypeByID(INPUT_ADDPLAYER_NAME, TextField.class);
final TextField rankNameField = findPaneOfTypeByID(INPUT_ADDRANK_NAME, TextField.class);
final Button addRankButton = findPaneOfTypeByID(BUTTON_ADD_RANK, Button.class);

final Button addBlockButton = findPaneOfTypeByID(BUTTON_ADD_BLOCK, Button.class);
final Button blockToolButton = findPaneOfTypeByID(BUTTON_BLOCK_TOOL, Button.class);

if (building.getColony().getPermissions().hasPermission(player, Action.EDIT_PERMISSIONS))
{
addPlayerButton.setEnabled(true);
playerNameField.setEnabled(true);
rankNameField.setEnabled(true);
addRankButton.setEnabled(true);
addBlockButton.setEnabled(true);
blockToolButton.setEnabled(true);
}
else
{
Expand All @@ -279,6 +286,8 @@ public void onOpened()
addPlayerButton.setEnabled(false);
playerNameField.setEnabled(false);
addRankButton.setEnabled(false);
addBlockButton.setEnabled(false);
blockToolButton.setEnabled(false);
}

findPaneOfTypeByID(TOWNHALL_RANK_TYPE_PICKER, DropDownList.class).setSelectedIndex(actionsRank.isColonyManager() ? 0 : (actionsRank.isHostile() ? 1 : 2));
Expand Down Expand Up @@ -422,6 +431,14 @@ else if (row < freeBlocks.size() + freePositions.size())
}
}

/**
* Gives the player a Permission Scepter.
*/
private void giveBlockTool(final Button button)
{
Network.getNetwork().sendToServer(new GiveToolMessage(buildingView, ModItems.permTool));
}

/**
* Fills the free blocks list in the GUI.
*/
Expand All @@ -444,13 +461,25 @@ public void updateElement(final int index, @NotNull final Pane rowPane)
{
if (index < freeBlocks.size())
{
rowPane.findPaneOfTypeByID(NAME_LABEL, Text.class).setText(Component.literal(BuiltInRegistries.BLOCK.getKey(freeBlocks.get(index)).toString()));
final Block block = freeBlocks.get(index);
final MutableComponent text = Component.literal(ForgeRegistries.BLOCKS.getKey(block).toString());
text.append(Component.literal("\n")).append(block.getName().withStyle(ChatFormatting.DARK_GRAY));
rowPane.findPaneOfTypeByID(NAME_LABEL, Text.class).setText(text);
}
else
{
final BlockPos pos = freePositions.get(index - freeBlocks.size());
rowPane.findPaneOfTypeByID(NAME_LABEL, Text.class).setText(Component.literal(pos.getX() + " " + pos.getY() + " " + pos.getZ()));
final MutableComponent text = Component.literal(pos.getX() + " " + pos.getY() + " " + pos.getZ());
if (building.getColony().getWorld().isLoaded(pos))
{
final BlockState state = building.getColony().getWorld().getBlockState(pos);
text.append(Component.literal("\n")).append(state.getBlock().getName().withStyle(ChatFormatting.DARK_GRAY));
}
rowPane.findPaneOfTypeByID(NAME_LABEL, Text.class).setText(text);
}

final boolean canEdit = building.getColony().getPermissions().hasPermission(Minecraft.getInstance().player, Action.EDIT_PERMISSIONS);
rowPane.findPaneOfTypeByID(BUTTON_REMOVE_BLOCK, Button.class).setEnabled(canEdit);
}
});
}
Expand All @@ -467,7 +496,7 @@ private void addBlock()
{
final Block block = BuiltInRegistries.BLOCK.get(new ResourceLocation(inputText));

if (block != null)
if (block != null && !block.defaultBlockState().isAir())
{
building.getColony().addFreeBlock(block);
new ChangeFreeToInteractBlockMessage(building.getColony(), block, ChangeFreeToInteractBlockMessage.MessageType.ADD_BLOCK).sendToServer();
Expand Down
102 changes: 92 additions & 10 deletions src/main/java/com/minecolonies/core/items/ItemScepterPermission.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,43 @@

import com.minecolonies.api.colony.IColonyManager;
import com.minecolonies.api.colony.IColonyView;
import com.minecolonies.api.colony.permissions.Action;
import com.minecolonies.api.items.IBlockOverlayItem;
import com.minecolonies.api.util.MessageUtils;
import com.minecolonies.core.network.messages.server.colony.ChangeFreeToInteractBlockMessage;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.ChatFormatting;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.InteractionResultHolder;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.InteractionResultHolder;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.InteractionHand;
import net.minecraft.core.BlockPos;
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.phys.AABB;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import static com.minecolonies.api.util.constant.translation.ToolTranslationConstants.*;

/**
* Permission scepter. used to add free to interact blocks or positions to the colonies permission list
*/
public class ItemScepterPermission extends AbstractItemMinecolonies
public class ItemScepterPermission extends AbstractItemMinecolonies implements IBlockOverlayItem
{
/**
* The NBT tag of the mode
Expand All @@ -40,6 +55,10 @@ public class ItemScepterPermission extends AbstractItemMinecolonies
*/
private static final String TAG_VALUE_MODE_LOCATION = "modeLocation";

private static final int GREEN_OVERLAY = 0xFF00FF00;
private static final int BLOCK_OVERLAY_RANGE_XZ = 32;
private static final int BLOCK_OVERLAY_RANGE_Y = 6;

/**
* constructor.
* <p>
Expand All @@ -62,10 +81,13 @@ private static InteractionResult handleAddBlockType(
final BlockState blockState = iColonyView.getWorld().getBlockState(pos);
final Block block = blockState.getBlock();

final ChangeFreeToInteractBlockMessage.MessageType type = Screen.hasControlDown()
? ChangeFreeToInteractBlockMessage.MessageType.REMOVE_BLOCK
: ChangeFreeToInteractBlockMessage.MessageType.ADD_BLOCK;
final ChangeFreeToInteractBlockMessage message = new ChangeFreeToInteractBlockMessage(
iColonyView,
block,
ChangeFreeToInteractBlockMessage.MessageType.ADD_BLOCK);
type);
message.sendToServer();

return InteractionResult.SUCCESS;
Expand All @@ -78,7 +100,10 @@ private static InteractionResult handleAddLocation(
final BlockPos pos,
final IColonyView iColonyView)
{
final ChangeFreeToInteractBlockMessage message = new ChangeFreeToInteractBlockMessage(iColonyView, pos, ChangeFreeToInteractBlockMessage.MessageType.ADD_BLOCK);
final ChangeFreeToInteractBlockMessage.MessageType type = Screen.hasControlDown()
? ChangeFreeToInteractBlockMessage.MessageType.REMOVE_BLOCK
: ChangeFreeToInteractBlockMessage.MessageType.ADD_BLOCK;
final ChangeFreeToInteractBlockMessage message = new ChangeFreeToInteractBlockMessage(iColonyView, pos, type);
message.sendToServer();

return InteractionResult.SUCCESS;
Expand Down Expand Up @@ -161,6 +186,63 @@ private static void toggleItemMode(final Player playerIn, final CompoundTag comp
}
}

@NotNull
@Override
public List<OverlayBox> getOverlayBoxes(@NotNull final Level world, @NotNull final Player player, @NotNull final ItemStack stack)
{
final List<OverlayBox> boxes = new ArrayList<>();
final IColonyView colony = IColonyManager.getInstance().getClosestColonyView(world, player.blockPosition());
if (colony == null || !colony.getPermissions().hasPermission(player, Action.EDIT_PERMISSIONS))
{
return boxes;
}

final String itemMode = stack.getOrCreateTag().getString(TAG_ITEM_MODE);
switch (itemMode)
{
case TAG_VALUE_MODE_BLOCK:
final Set<Block> freeBlocks = new HashSet<>(colony.getFreeBlocks());
for (final BlockPos pos : BlockPos.withinManhattan(player.blockPosition(), BLOCK_OVERLAY_RANGE_XZ, BLOCK_OVERLAY_RANGE_Y, BLOCK_OVERLAY_RANGE_XZ))
{
if (world.isLoaded(pos) && freeBlocks.contains(world.getBlockState(pos).getBlock()))
{
boxes.add(new OverlayBox(AABB.unitCubeFromLowerCorner(Vec3.atLowerCornerOf(pos)), GREEN_OVERLAY, 0.02f, true));
}
}
break;
case TAG_VALUE_MODE_LOCATION:
default:
for (final BlockPos pos : colony.getFreePositions())
{
boxes.add(new OverlayBox(AABB.unitCubeFromLowerCorner(Vec3.atLowerCornerOf(pos)), GREEN_OVERLAY, 0.02f, true));
}
break;
}

return boxes;
}

@Override
public void appendHoverText(@NotNull final ItemStack stack, @Nullable final Level level,
@NotNull final List<Component> tooltip, @NotNull final TooltipFlag flags)
{
final String itemMode = stack.getOrCreateTag().getString(TAG_ITEM_MODE);
final MutableComponent mode;
switch (itemMode)
{
case TAG_VALUE_MODE_BLOCK:
mode = Component.translatable(TOOL_PERMISSION_SCEPTER_MODE_BLOCK);
break;
case TAG_VALUE_MODE_LOCATION:
default:
mode = Component.translatable(TOOL_PERMISSION_SCEPTER_MODE_LOCATION);
break;
}
tooltip.add(Component.translatable(TOOL_PERMISSION_SCEPTER_MODE, mode.withStyle(ChatFormatting.YELLOW)));

super.appendHoverText(stack, level, tooltip, flags);
}

@NotNull
private static InteractionResult handleItemAction(
final CompoundTag compound,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,13 @@ protected Action permissionNeeded()
@Override
protected void onExecute(final PlayPayloadContext ctxIn, final ServerPlayer player, final IColony colony)
{
//Verify player has permission to change this huts settings
if (msgType == MessageType.ADD_BLOCK)
final Player player = ctxIn.getSender();
if (player == null)
{
return;
}

if (type == MessageType.ADD_BLOCK)
{
switch (msgMode)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@
<view id="pageAddPlayer">
<text size="148 11" pos="26 65" color="black" label="$(com.minecolonies.coremod.gui.townhall.addplayer)"/>
<input id="addPlayerName" size="100 18" pos="26 76" maxlength="32"/>
<button id="addPlayer" size="19 19" pos="130 76" label="+"/>
<buttonimage id="addPlayer" size="14 15" pos="130 78" label="+" source="minecolonies:textures/gui/builderhut/builder_button_mini.png" textcolor="black"/>

<list id="users" size="148 121" pos="26 100">
<box size="100% 35" linewidth="1">
<text id="name" size="100 11" pos="5 2" color="black"/>
<button id="removePlayer" size="11 11" pos="7 2" align="TOP_RIGHT" label="X" textscale="0.5"/>
<text id="rank" size="129 11" pos="5 15" color="black" />
<label id="name" size="100 11" pos="5 2" color="black"/>
<buttonimage id="removePlayer" size="14 15" pos="2 1" align="TOP_RIGHT" source="minecolonies:textures/gui/button_x.png"/>
<label id="rank" size="129 11" pos="5 17" color="black" />
<dropdown id="rankPicker"
size="129 17"
pos="2 15"
pos="2 17"
maxContentHeight="100"
dropDownSize="129 100"
source="minecolonies:textures/gui/builderhut/builder_button_medium_large.png"
Expand Down Expand Up @@ -44,7 +44,7 @@
<view id="managePermissions">
<text size="148 11" pos="36 65" color="black" label="$(com.minecolonies.coremod.gui.townhall.addrank)"/>
<input id="addRankName" size="100 18" pos="36 80" maxlength="32"/>
<button id="buttonAddRank" size="19 19" pos="140 80" label="+"/>
<buttonimage id="buttonAddRank" size="14 15" pos="140 82" label="+" source="minecolonies:textures/gui/builderhut/builder_button_mini.png" textcolor="black"/>

<list id="rankButtonList" size="100 110" pos="46 105">
<box size="100% 15" linewidth="0">
Expand Down Expand Up @@ -79,9 +79,11 @@

<list id="rankList" size="138 120" pos="201 77">
<box size="100% 21" linewidth="1">
<text id="name" size="110 18" pos="2 2" color="black"/>
<button id="trigger" size="24 17" pos="2 2" align="TOP_RIGHT" label="$(com.minecolonies.coremod.gui.workerhuts.retrieveoff)"/>
<text id="index" pos="100 100"/>
<label id="name" size="110 18" pos="2 2" color="black"/>
<buttonimage id="trigger" size="29 15" pos="2 3" align="TOP_RIGHT" color="black"
label="$(com.minecolonies.coremod.gui.workerhuts.retrieveoff)"
source="minecolonies:textures/gui/builderhut/builder_button_very_small.png"/>
<label id="index" pos="100 100"/>
</box>
</list>

Expand All @@ -93,13 +95,13 @@

<text size="146 11" pos="26 65" color="black" label="$(com.minecolonies.coremod.gui.townhall.addblock)"/>
<input id="addBlockName" size="100 18" pos="26 76" maxlength="32"/>
<button id="addBlock" size="19 19" pos="130 76" label="+"/>

<buttonimage id="addBlock" size="14 15" pos="130 78" label="+" source="minecolonies:textures/gui/builderhut/builder_button_mini.png" textcolor="black"/>
<buttonimage id="blockTool" size="14 15" pos="146 78" source="minecolonies:textures/gui/scepterpermission.png"/>

<list id="blocks" size="148 171" pos="201 36">
<box size="100% 30" linewidth="1">
<text id="name" size="100 12" pos="5 2" color="black"/>
<button id="removeBlock" size="12 12" pos="5 2" align="TOP_RIGHT" label="X"/>
<label id="name" size="115 28" pos="5 2" color="black" wrap="true" textalign="TOP_LEFT"/>
<buttonimage id="removeBlock" size="14 15" pos="2 1" align="TOP_RIGHT" source="minecolonies:textures/gui/button_x.png"/>
</box>
</list>
</view>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -751,6 +751,7 @@
"item.minecolonies.spear": "Spear",

"com.minecolonies.coremod.item.permissionscepter.setmode": "Set to mode %s.",
"com.minecolonies.coremod.item.permissionscepter.mode": "Tool Mode: %s",
"com.minecolonies.coremod.item.permissionscepter.mode.block": "block",
"com.minecolonies.coremod.item.permissionscepter.mode.location": "location",
"com.minecolonies.coremod.item.permissionscepter.permission.deny": "You do not have permission to edit blocks with this tool!",
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 9070dc0

Please # to comment.