Merge pull request #323 from BentoBoxWorld/develop

Release 2.15.0
This commit is contained in:
tastybento 2024-07-20 10:51:17 -07:00 committed by GitHub
commit fd20a9eb81
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 221 additions and 124 deletions

View File

@ -71,7 +71,7 @@
<!-- Do not change unless you want different name for local builds. --> <!-- Do not change unless you want different name for local builds. -->
<build.number>-LOCAL</build.number> <build.number>-LOCAL</build.number>
<!-- This allows to change between versions. --> <!-- This allows to change between versions. -->
<build.version>2.14.1</build.version> <build.version>2.15.0</build.version>
<sonar.projectKey>BentoBoxWorld_Level</sonar.projectKey> <sonar.projectKey>BentoBoxWorld_Level</sonar.projectKey>
<sonar.organization>bentobox-world</sonar.organization> <sonar.organization>bentobox-world</sonar.organization>
<sonar.host.url>https://sonarcloud.io</sonar.host.url> <sonar.host.url>https://sonarcloud.io</sonar.host.url>

View File

@ -216,15 +216,32 @@ public class LevelsManager {
* *
* @param world - world where the island is * @param world - world where the island is
* @param targetPlayer - target player UUID * @param targetPlayer - target player UUID
* @param ownerOnly - return level only if the target player is the owner
* @return Level of the player's island or zero if player is unknown or UUID is * @return Level of the player's island or zero if player is unknown or UUID is
* null * null
*/ */
public long getIslandLevel(@NonNull World world, @Nullable UUID targetPlayer) { public long getIslandLevel(@NonNull World world, @Nullable UUID targetPlayer) {
return getIslandLevel(world, targetPlayer, false);
}
/**
* Get level of island from cache for a player.
*
* @param world - world where the island is
* @param targetPlayer - target player UUID
* @param ownerOnly - return level only if the target player is the owner
* @return Level of the player's island or zero if player is unknown or UUID is
* null
*/
public long getIslandLevel(@NonNull World world, @Nullable UUID targetPlayer, boolean ownerOnly) {
if (targetPlayer == null) if (targetPlayer == null)
return 0L; return 0L;
// Get the island // Get the island
Island island = addon.getIslands().getIsland(world, targetPlayer); Island island = addon.getIslands().getIsland(world, targetPlayer);
return island == null ? 0L : getLevelsData(island).getLevel(); if (island == null || island.getOwner() == null || (ownerOnly && !island.getOwner().equals(targetPlayer))) {
return 0L;
}
return getLevelsData(island).getLevel();
} }
/** /**

View File

@ -41,6 +41,9 @@ public class PlaceholderManager {
// Island Level // Island Level
bpm.registerPlaceholder(addon, gm.getDescription().getName().toLowerCase() + "_island_level", bpm.registerPlaceholder(addon, gm.getDescription().getName().toLowerCase() + "_island_level",
user -> addon.getManager().getIslandLevelString(gm.getOverWorld(), user.getUniqueId())); user -> addon.getManager().getIslandLevelString(gm.getOverWorld(), user.getUniqueId()));
// Island Level owner only
bpm.registerPlaceholder(addon, gm.getDescription().getName().toLowerCase() + "_island_level_owner",
user -> String.valueOf(addon.getManager().getIslandLevel(gm.getOverWorld(), user.getUniqueId(), true)));
// Unformatted island level // Unformatted island level
bpm.registerPlaceholder(addon, gm.getDescription().getName().toLowerCase() + "_island_level_raw", bpm.registerPlaceholder(addon, gm.getDescription().getName().toLowerCase() + "_island_level_raw",
user -> String.valueOf(addon.getManager().getIslandLevel(gm.getOverWorld(), user.getUniqueId()))); user -> String.valueOf(addon.getManager().getIslandLevel(gm.getOverWorld(), user.getUniqueId())));

View File

@ -8,11 +8,14 @@ import java.util.Optional;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.PlayerInventory; import org.bukkit.inventory.PlayerInventory;
import org.eclipse.jdt.annotation.NonNull;
import world.bentobox.bentobox.api.commands.CompositeCommand; import world.bentobox.bentobox.api.commands.CompositeCommand;
import world.bentobox.bentobox.api.localization.TextVariables;
import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.util.Util; import world.bentobox.bentobox.util.Util;
import world.bentobox.level.Level; import world.bentobox.level.Level;
import world.bentobox.level.objects.IslandLevels;
import world.bentobox.level.panels.ValuePanel; import world.bentobox.level.panels.ValuePanel;
import world.bentobox.level.util.Utils; import world.bentobox.level.util.Utils;
@ -112,6 +115,19 @@ public class IslandValueCommand extends CompositeCommand
"[value]", (underWater * value) + ""), "[value]", (underWater * value) + ""),
MATERIAL, Utils.prettifyObject(material, user)); MATERIAL, Utils.prettifyObject(material, user));
} }
// Show how many have been placed and how many are allowed
@NonNull
IslandLevels lvData = this.addon.getManager()
.getLevelsData(getIslands().getPrimaryIsland(getWorld(), user.getUniqueId()));
int count = lvData.getMdCount().getOrDefault(material, 0) + lvData.getUwCount().getOrDefault(material, 0);
user.sendMessage("level.conversations.you-have", TextVariables.NUMBER,
String.valueOf(count));
int limit = this.addon.getBlockConfig().getBlockLimits().getOrDefault(material, -1);
if (limit > 0) {
user.sendMessage("level.conversations.you-can-place", TextVariables.NUMBER,
String.valueOf(limit));
}
} }
else else
{ {

View File

@ -62,7 +62,7 @@ public class IslandLevels implements DataObject {
private Map<Material, Integer> uwCount; private Map<Material, Integer> uwCount;
/** /**
* MaterialData count - count of all blocks * MaterialData count - count of all blocks excluding under water
*/ */
@Expose @Expose
private Map<Material, Integer> mdCount; private Map<Material, Integer> mdCount;
@ -162,6 +162,7 @@ public class IslandLevels implements DataObject {
} }
/** /**
* The count of underwater blocks
* @return the uwCount * @return the uwCount
*/ */
public Map<Material, Integer> getUwCount() { public Map<Material, Integer> getUwCount() {
@ -169,6 +170,7 @@ public class IslandLevels implements DataObject {
} }
/** /**
* Underwater blocks
* @param uwCount the uwCount to set * @param uwCount the uwCount to set
*/ */
public void setUwCount(Map<Material, Integer> uwCount) { public void setUwCount(Map<Material, Integer> uwCount) {
@ -176,6 +178,7 @@ public class IslandLevels implements DataObject {
} }
/** /**
* All blocks count except for underwater blocks
* @return the mdCount * @return the mdCount
*/ */
public Map<Material, Integer> getMdCount() { public Map<Material, Integer> getMdCount() {
@ -183,6 +186,7 @@ public class IslandLevels implements DataObject {
} }
/** /**
* All blocks except for underwater blocks
* @param mdCount the mdCount to set * @param mdCount the mdCount to set
*/ */
public void setMdCount(Map<Material, Integer> mdCount) { public void setMdCount(Map<Material, Integer> mdCount) {

View File

@ -59,7 +59,7 @@ public class DetailsPanel {
} }
// By default no-filters are active. // By default no-filters are active.
this.activeTab = Tab.ALL_BLOCKS; this.activeTab = Tab.VALUE_BLOCKS;
this.activeFilter = Filter.NAME; this.activeFilter = Filter.NAME;
this.materialCountList = new ArrayList<>(Material.values().length); this.materialCountList = new ArrayList<>(Material.values().length);
@ -111,6 +111,28 @@ public class DetailsPanel {
this.materialCountList.clear(); this.materialCountList.clear();
switch (this.activeTab) { switch (this.activeTab) {
case VALUE_BLOCKS -> {
Map<Material, Integer> materialCountMap = new EnumMap<>(Material.class);
materialCountMap.putAll(this.levelsData.getMdCount());
// Add underwater blocks.
this.levelsData.getUwCount().forEach((material, count) -> materialCountMap.put(material,
materialCountMap.computeIfAbsent(material, key -> 0) + count));
// Remove zero value blocks
materialCountMap.entrySet().removeIf(en -> {
Integer value = this.addon.getBlockConfig().getValue(world, en.getKey());
return value == null || value == 0;
});
materialCountMap.entrySet().stream().sorted((Map.Entry.comparingByKey())).forEachOrdered(entry -> {
if (entry.getValue() > 0) {
this.materialCountList.add(new Pair<>(entry.getKey(), entry.getValue()));
}
});
}
case ALL_BLOCKS -> { case ALL_BLOCKS -> {
Map<Material, Integer> materialCountMap = new EnumMap<>(Material.class); Map<Material, Integer> materialCountMap = new EnumMap<>(Material.class);
@ -220,7 +242,7 @@ public class DetailsPanel {
builder.description(this.user.getTranslation(this.world, template.description())); builder.description(this.user.getTranslation(this.world, template.description()));
} }
Tab tab = Enums.getIfPresent(Tab.class, String.valueOf(template.dataMap().get("tab"))).or(Tab.ALL_BLOCKS); Tab tab = Enums.getIfPresent(Tab.class, String.valueOf(template.dataMap().get("tab"))).or(Tab.VALUE_BLOCKS);
// Get only possible actions, by removing all inactive ones. // Get only possible actions, by removing all inactive ones.
List<ItemTemplateRecord.ActionRecords> activeActions = new ArrayList<>(template.actions()); List<ItemTemplateRecord.ActionRecords> activeActions = new ArrayList<>(template.actions());
@ -605,6 +627,10 @@ public class DetailsPanel {
*/ */
ALL_BLOCKS, ALL_BLOCKS,
/** /**
* Blocks that have value
*/
VALUE_BLOCKS,
/**
* Above Sea level Tab. * Above Sea level Tab.
*/ */
ABOVE_SEA_LEVEL, ABOVE_SEA_LEVEL,

View File

@ -112,6 +112,11 @@ level:
limit: "&7 Block limit: &e [number]" limit: "&7 Block limit: &e [number]"
count: "&7 Number of blocks: &e [number]" count: "&7 Number of blocks: &e [number]"
calculated: "&7 Calculated value: &e [number]" calculated: "&7 Calculated value: &e [number]"
value_blocks:
name: "&f&l All Blocks With Value"
description: |-
&7 Display all blocks
&7 with value on island.
all_blocks: all_blocks:
name: "&f&l All Blocks" name: "&f&l All Blocks"
description: |- description: |-
@ -211,3 +216,7 @@ level:
value-underwater: "&7 The value of '[material]' below sea-level: &e[value]" value-underwater: "&7 The value of '[material]' below sea-level: &e[value]"
# Message that is sent to user when he does not hold any items in hand. # Message that is sent to user when he does not hold any items in hand.
empty-hand: "&c There are no blocks in your hand" empty-hand: "&c There are no blocks in your hand"
# Message when showing how many have been placed of a block
you-have: "&7 You have [number] at last count."
# Message about the limit
you-can-place: "&7 You can place up to [number] and have them count"

View File

@ -24,6 +24,28 @@ detail_panel:
1: 1:
# Column number # Column number
2: 2:
# Icon is a Bukkit Material.
icon: ICE
# Title of the button shown to the user. This is a reference and the reference will be translatable in the locale file
title: level.gui.buttons.value_blocks.name
# Description of the button shown to the user in the lore. This is a reference and the reference will be translatable in the locale file
description: level.gui.buttons.value_blocks.description
# The data section is a key-value list of data relavent for this button. It is interpreted by the code implemented the panel.
# The convention is to specify the type and the panel tab that will open if pressed. These are Enums in the code.
data:
# Type button will go to the ALL_BLOCKS tab when clicked.
type: TAB
tab: VALUE_BLOCKS
# Actions cover what happens if the button is clicked or the mouse is moved over it. There can be multiple actions possible for different
# click-types.
actions:
# Each action has an arbitrary descriptive name to define it.
view:
# The click-type is the same as the bukkit {@link org.bukkit.event.inventory.ClickType}. UNKNOWN is the default.
click-type: unknown
# tooltip is a locale reference that will be translated for the user and shown when they hover over the button.
tooltip: level.gui.tips.click-to-view
3:
# Icon is a Bukkit Material. # Icon is a Bukkit Material.
icon: STONE icon: STONE
# Title of the button shown to the user. This is a reference and the reference will be translatable in the locale file # Title of the button shown to the user. This is a reference and the reference will be translatable in the locale file
@ -45,7 +67,7 @@ detail_panel:
click-type: unknown click-type: unknown
# tooltip is a locale reference that will be translated for the user and shown when they hover over the button. # tooltip is a locale reference that will be translated for the user and shown when they hover over the button.
tooltip: level.gui.tips.click-to-view tooltip: level.gui.tips.click-to-view
3: 4:
icon: GRASS_BLOCK icon: GRASS_BLOCK
title: level.gui.buttons.above_sea_level.name title: level.gui.buttons.above_sea_level.name
description: level.gui.buttons.above_sea_level.description description: level.gui.buttons.above_sea_level.description
@ -56,7 +78,7 @@ detail_panel:
view: view:
click-type: unknown click-type: unknown
tooltip: level.gui.tips.click-to-view tooltip: level.gui.tips.click-to-view
4: 5:
icon: WATER_BUCKET icon: WATER_BUCKET
title: level.gui.buttons.underwater.name title: level.gui.buttons.underwater.name
description: level.gui.buttons.underwater.description description: level.gui.buttons.underwater.description
@ -67,7 +89,7 @@ detail_panel:
view: view:
click-type: unknown click-type: unknown
tooltip: level.gui.tips.click-to-view tooltip: level.gui.tips.click-to-view
5: 6:
icon: SPAWNER icon: SPAWNER
title: level.gui.buttons.spawner.name title: level.gui.buttons.spawner.name
description: level.gui.buttons.spawner.description description: level.gui.buttons.spawner.description