Improved the feedback messages when a player tries to create a shop via
command. * If the player targets a container (regardless of whether it is supported), we assume that he might be trying to create a player shop. However, unlike before this only affects the default shop type that is chosen if the player does not specify a shop type himself. * It is now possible to create admin shops via command even when targeting a container. However, the admin shop type has to be explicitly specified as command argument. * When a player shop type is selected, we send appropriate feedback messages depending on whether player shop creation via command is enabled, whether a container is targeted, and whether it is a supported type of container. * When not specifying a shop object type, we pick the first shop object type that can be used by the player. This is consistent between the creation of player and admin shops now. Messages: * Added 'must-target-container'. * Added 'no-player-shops-via-command'. * Removed 'no-admin-shop-type-selected'. * Removed 'no-player-shop-type-selected'.master
parent
ccc76cf363
commit
0dfc51a6b1
|
@ -10,6 +10,11 @@ Date format: (YYYY-MM-DD)
|
|||
* Fixed: Text#parse can now also parse alternative color codes starting with '&'. This has an effect when some messages of the specified language file cannot be loaded and the plugin then uses the default messages instead.
|
||||
* Added warning output when the language file misses messages, or contains unexpected messages.
|
||||
* Changed: Players in creative mode are no longer ignored when using the shop creation item.
|
||||
* Improved the feedback messages when a player tries to create a shop via command.
|
||||
* If the player targets a container (regardless of whether it is supported), we assume that he might be trying to create a player shop. However, unlike before this only affects the default shop type that is chosen if the player does not specify a shop type himself.
|
||||
* It is now possible to create admin shops via command even when targeting a container. However, the admin shop type has to be explicitly specified as command argument.
|
||||
* When a player shop type is selected, we send appropriate feedback messages depending on whether player shop creation via command is enabled, whether a container is targeted, and whether it is a supported type of container.
|
||||
* When not specifying a shop object type, we pick the first shop object type that can be used by the player. This is consistent between the creation of player and admin shops now.
|
||||
|
||||
Migration notes:
|
||||
* The folder structure has changed:
|
||||
|
@ -24,6 +29,10 @@ Messages:
|
|||
* 'cant-trade-with-own-shop' -> 'cannot-trade-with-own-shop'
|
||||
* 'cant-trade-while-owner-online' -> 'cannot-trade-while-owner-online'
|
||||
* 'cant-trade-with-shop-missing-container' -> 'cannot-trade-with-shop-missing-container'
|
||||
* Added 'must-target-container'.
|
||||
* Added 'no-player-shops-via-command'.
|
||||
* Removed 'no-admin-shop-type-selected'.
|
||||
* Removed 'no-player-shop-type-selected'.
|
||||
|
||||
You will have to manually update your custom language files to adapt for these changes.
|
||||
|
||||
|
|
|
@ -129,14 +129,14 @@ public class Messages {
|
|||
public static Text containerSelected = Text.parse("&aContainer selected! Right-click a block to place your shopkeeper.");
|
||||
public static Text unsupportedContainer = Text.parse("&7This type of container cannot be used for shops.");
|
||||
public static Text mustSelectContainer = Text.parse("&7You must right-click a container before placing your shopkeeper.");
|
||||
public static Text mustTargetContainer = Text.parse("&7You must target a container to place this type of shop.");
|
||||
public static Text invalidContainer = Text.parse("&7The selected block is not a valid container!");
|
||||
public static Text containerTooFarAway = Text.parse("&7The shopkeeper's container is too far away!");
|
||||
public static Text containerNotPlaced = Text.parse("&7You must select a container you have recently placed!");
|
||||
public static Text containerAlreadyInUse = Text.parse("&7Another shopkeeper is already using the selected container!");
|
||||
public static Text noContainerAccess = Text.parse("&7You cannot access the selected container!");
|
||||
public static Text tooManyShops = Text.parse("&7You have too many shops!");
|
||||
public static Text noAdminShopTypeSelected = Text.parse("&7You have to select an admin shop type!");
|
||||
public static Text noPlayerShopTypeSelected = Text.parse("&7You have to select a player shop type!");
|
||||
public static Text noPlayerShopsViaCommand = Text.parse("&7Player shops can only be created via the shop creation item!");
|
||||
public static Text shopCreateFail = Text.parse("&7You cannot create a shopkeeper there.");
|
||||
|
||||
public static Text typeNewName = Text.parse("&aPlease type the shop's name into the chat.\n"
|
||||
|
|
|
@ -11,7 +11,6 @@ import org.bstats.bukkit.Metrics;
|
|||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.configuration.Configuration;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
@ -60,7 +59,6 @@ import com.nisovin.shopkeepers.shopkeeper.SKTradingRecipe;
|
|||
import com.nisovin.shopkeepers.shopkeeper.offers.SKBookOffer;
|
||||
import com.nisovin.shopkeepers.shopkeeper.offers.SKPriceOffer;
|
||||
import com.nisovin.shopkeepers.shopkeeper.offers.SKTradingOffer;
|
||||
import com.nisovin.shopkeepers.shopobjects.AbstractShopObjectType;
|
||||
import com.nisovin.shopkeepers.shopobjects.SKDefaultShopObjectTypes;
|
||||
import com.nisovin.shopkeepers.shopobjects.SKShopObjectTypesRegistry;
|
||||
import com.nisovin.shopkeepers.shopobjects.citizens.CitizensShops;
|
||||
|
@ -630,20 +628,6 @@ public class SKShopkeepersPlugin extends JavaPlugin implements ShopkeepersPlugin
|
|||
return defaultShopObjectTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default shop object type.
|
||||
*
|
||||
* <p>
|
||||
* Usually this will be the villager entity shop object type. However, there are no guarantees that this might not
|
||||
* get changed or be configurable in the future.
|
||||
*
|
||||
* @return the default shop object type
|
||||
*/
|
||||
public AbstractShopObjectType<?> getDefaultShopObjectType() {
|
||||
// Default: Villager entity shop object type.
|
||||
return this.getDefaultShopObjectTypes().getLivingShopObjectTypes().get(EntityType.VILLAGER);
|
||||
}
|
||||
|
||||
// SHOPKEEPER NAMING
|
||||
|
||||
public ShopkeeperNaming getShopkeeperNaming() {
|
||||
|
|
|
@ -20,7 +20,6 @@ import com.nisovin.shopkeepers.api.shopkeeper.ShopCreationData;
|
|||
import com.nisovin.shopkeepers.api.shopkeeper.ShopType;
|
||||
import com.nisovin.shopkeepers.api.shopkeeper.ShopkeeperRegistry;
|
||||
import com.nisovin.shopkeepers.api.shopkeeper.admin.AdminShopCreationData;
|
||||
import com.nisovin.shopkeepers.api.shopkeeper.admin.AdminShopType;
|
||||
import com.nisovin.shopkeepers.api.shopkeeper.player.PlayerShopCreationData;
|
||||
import com.nisovin.shopkeepers.api.shopkeeper.player.PlayerShopType;
|
||||
import com.nisovin.shopkeepers.api.shopobjects.ShopObjectType;
|
||||
|
@ -34,7 +33,7 @@ import com.nisovin.shopkeepers.commands.lib.CommandInput;
|
|||
import com.nisovin.shopkeepers.commands.lib.CommandRegistry;
|
||||
import com.nisovin.shopkeepers.commands.lib.PlayerCommand;
|
||||
import com.nisovin.shopkeepers.commands.lib.arguments.OptionalArgument;
|
||||
import com.nisovin.shopkeepers.container.ShopContainers;
|
||||
import com.nisovin.shopkeepers.util.ItemUtils;
|
||||
import com.nisovin.shopkeepers.util.PermissionUtils;
|
||||
import com.nisovin.shopkeepers.util.TextUtils;
|
||||
|
||||
|
@ -125,63 +124,50 @@ public class ShopkeepersCommand extends BaseCommand {
|
|||
ShopType<?> shopType = context.get(ARGUMENT_SHOP_TYPE);
|
||||
ShopObjectType<?> shopObjType = context.get(ARGUMENT_OBJECT_TYPE);
|
||||
|
||||
boolean createPlayerShop = (Settings.createPlayerShopWithCommand && ShopContainers.isSupportedContainer(targetBlock.getType()));
|
||||
if (createPlayerShop) {
|
||||
// Create player shopkeeper:
|
||||
|
||||
// Default shop type and shop object type: First useable player shop type and shop object type.
|
||||
// We use different defaults depending on whether the player might be trying to create a player or admin shop:
|
||||
boolean containerTargeted = ItemUtils.isContainer(targetBlock.getType());
|
||||
boolean maybeCreatePlayerShop = containerTargeted;
|
||||
if (maybeCreatePlayerShop) {
|
||||
// Default shop type and shop object type: First usable player shop type and shop object type.
|
||||
if (shopType == null) {
|
||||
shopType = plugin.getShopTypeRegistry().getDefaultSelection(player);
|
||||
}
|
||||
if (shopObjType == null) {
|
||||
shopObjType = plugin.getShopObjectTypeRegistry().getDefaultSelection(player);
|
||||
}
|
||||
|
||||
if (shopType == null || shopObjType == null) {
|
||||
// The player cannot create shops at all:
|
||||
TextUtils.sendMessage(player, Messages.noPermission);
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate the selected shop type:
|
||||
if (!(shopType instanceof PlayerShopType)) {
|
||||
// Only player shop types are allowed here:
|
||||
TextUtils.sendMessage(player, Messages.noPlayerShopTypeSelected);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// Create admin shopkeeper:
|
||||
|
||||
// Check permission:
|
||||
if (!PermissionUtils.hasPermission(player, ShopkeepersPlugin.ADMIN_PERMISSION)) {
|
||||
TextUtils.sendMessage(sender, Messages.noPermission);
|
||||
return;
|
||||
}
|
||||
|
||||
// Default shop type and shop object type:
|
||||
if (shopType == null) {
|
||||
shopType = DefaultShopTypes.ADMIN();
|
||||
}
|
||||
if (shopObjType == null) {
|
||||
shopObjType = plugin.getDefaultShopObjectType();
|
||||
}
|
||||
assert shopType != null && shopObjType != null;
|
||||
|
||||
// Validate the selected shop type:
|
||||
if (!(shopType instanceof AdminShopType)) {
|
||||
// Only admin shop types are allowed here:
|
||||
TextUtils.sendMessage(player, Messages.noAdminShopTypeSelected);
|
||||
return;
|
||||
// Note: Shop type permissions are checked afterwards during shop creation.
|
||||
}
|
||||
}
|
||||
|
||||
if (shopObjType == null) {
|
||||
shopObjType = plugin.getShopObjectTypeRegistry().getDefaultSelection(player);
|
||||
}
|
||||
if (shopType == null || shopObjType == null) {
|
||||
// The player cannot create shops at all:
|
||||
TextUtils.sendMessage(player, Messages.noPermission);
|
||||
return;
|
||||
}
|
||||
assert shopType != null && shopObjType != null;
|
||||
boolean isPlayerShopType = (shopType instanceof PlayerShopType);
|
||||
|
||||
if (isPlayerShopType) {
|
||||
if (!Settings.createPlayerShopWithCommand) {
|
||||
TextUtils.sendMessage(player, Messages.noPlayerShopsViaCommand);
|
||||
return;
|
||||
} else if (!containerTargeted) {
|
||||
TextUtils.sendMessage(player, Messages.mustTargetContainer);
|
||||
return;
|
||||
}
|
||||
// Note: We check if the targeted container is valid / supported during shop creation.
|
||||
}
|
||||
|
||||
// Determine spawn location:
|
||||
Location spawnLocation = plugin.getShopkeeperCreation().determineSpawnLocation(player, targetBlock, targetBlockFace);
|
||||
|
||||
// Shop creation data:
|
||||
ShopCreationData shopCreationData;
|
||||
if (createPlayerShop) {
|
||||
if (isPlayerShopType) {
|
||||
// Create player shopkeeper:
|
||||
shopCreationData = PlayerShopCreationData.create(player, shopType, shopObjType, spawnLocation, targetBlockFace, targetBlock);
|
||||
} else {
|
||||
|
|
|
@ -179,12 +179,8 @@ class CreateListener implements Listener {
|
|||
}
|
||||
assert ShopContainers.isSupportedContainer(selectedContainer.getType()); // Checked above already
|
||||
|
||||
// Validate the selected shop type:
|
||||
if (!(shopType instanceof PlayerShopType)) {
|
||||
// Only player shop types are allowed here:
|
||||
TextUtils.sendMessage(player, Messages.noPlayerShopTypeSelected);
|
||||
return;
|
||||
}
|
||||
// Only player shops can be selected currently. TODO Change that?
|
||||
assert shopType instanceof PlayerShopType;
|
||||
|
||||
// Determine spawn location:
|
||||
BlockFace clickedBlockFace = event.getBlockFace();
|
||||
|
|
|
@ -18,7 +18,7 @@ public class SKShopTypesRegistry extends AbstractSelectableTypeRegistry<Abstract
|
|||
// TODO This currently skips all shop types that are not PlayerShopType.
|
||||
// Maybe include the admin shop types here for players which are admins, because there /could/ be different
|
||||
// types of admin shops in the future.
|
||||
// Maybe include other types of shop types here, is custom ones get registered?
|
||||
// Maybe include other types of shop types here, if custom ones get registered?
|
||||
return super.canBeSelected(player, type) && (type instanceof PlayerShopType);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ import com.nisovin.shopkeepers.container.ShopContainers;
|
|||
import com.nisovin.shopkeepers.pluginhandlers.TownyHandler;
|
||||
import com.nisovin.shopkeepers.pluginhandlers.WorldGuardHandler;
|
||||
import com.nisovin.shopkeepers.shopkeeper.AbstractShopType;
|
||||
import com.nisovin.shopkeepers.util.ItemUtils;
|
||||
import com.nisovin.shopkeepers.util.Log;
|
||||
import com.nisovin.shopkeepers.util.TextUtils;
|
||||
import com.nisovin.shopkeepers.util.Validate;
|
||||
|
@ -45,8 +46,12 @@ public abstract class AbstractPlayerShopType<T extends AbstractPlayerShopkeeper>
|
|||
// Validate container block:
|
||||
Block containerBlock = playerShopCreationData.getShopContainer();
|
||||
if (!ShopContainers.isSupportedContainer(containerBlock.getType())) {
|
||||
// The block is not / no longer a supported container:
|
||||
TextUtils.sendMessage(creator, Messages.invalidContainer);
|
||||
// The block is not / no longer a supported type of container:
|
||||
if (ItemUtils.isContainer(containerBlock.getType())) {
|
||||
TextUtils.sendMessage(creator, Messages.unsupportedContainer);
|
||||
} else {
|
||||
TextUtils.sendMessage(creator, Messages.invalidContainer);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -170,14 +170,14 @@ msg-trading-title-default: "Händler"
|
|||
msg-container-selected: "&aBehälter ausgewählt! Klicke mit rechts auf einen Block, um den Shop zu platzieren."
|
||||
msg-unsupported-container: "&7Diese Art von Behälter kann nicht für Shops benutzt werden."
|
||||
msg-must-select-container: "&7Du musst zuerst einen Behälter mit rechts anklicken, bevor du den Shop platzieren kannst."
|
||||
must-target-container: "&7Du musst einen Behälter anvisieren, um diesen Shop zu platzieren."
|
||||
msg-invalid-container: "&7Der ausgewählte Block ist kein gültiger Behälter!"
|
||||
msg-container-too-far-away: "&7Der Behälter des Shops ist zu weit entfernt!"
|
||||
msg-container-not-placed: "&7Du musst einen Behälter auswählen, den du kürzlich platziert hast!"
|
||||
msg-container-already-in-use: "&7Ein anderer Shop benutzt bereits den ausgewählten Behälter!"
|
||||
msg-no-container-access: "&7Du hast keinen Zugriff auf den ausgewählten Behälter!"
|
||||
msg-too-many-shops: "&7Du hast bereits zu viele Shops!"
|
||||
msg-no-admin-shop-type-selected: "&7Du musst einen Admin-Shop Typ auswählen!"
|
||||
msg-no-player-shop-type-selected: "&7Du musst einen Spieler-Shop Typ auswählen!"
|
||||
no-player-shops-via-command: "&7Spieler-Shops können nur mit dem Shop-Erstellungs Item erzeugt werden!"
|
||||
msg-shop-create-fail: "&7Du kannst dort keinen Shop erstellen."
|
||||
|
||||
msg-type-new-name: "&aBitte gebe den neuen Shop-Namen im Chat ein.\n &aTippe Minus (-) ein, um den Namen zu entfernen."
|
||||
|
|
|
@ -171,14 +171,14 @@ trading-title-default: "Shopkeeper"
|
|||
container-selected: "&aContainer selected! Right-click a block to place your shopkeeper."
|
||||
unsupported-container: "&7This type of container cannot be used for shops."
|
||||
must-select-container: "&7You must right-click a container before placing your shopkeeper."
|
||||
must-target-container: "&7You must target a container to place this type of shop."
|
||||
invalid-container: "&7The selected block is not a valid container!"
|
||||
container-too-far-away: "&7The shopkeeper's container is too far away!"
|
||||
container-not-placed: "&7You must select a container you have recently placed!"
|
||||
container-already-in-use: "&7Another shopkeeper is already using the selected container!"
|
||||
no-container-access: "&7You cannot access the selected container!"
|
||||
too-many-shops: "&7You have too many shops!"
|
||||
no-admin-shop-type-selected: "&7You have to select an admin shop type!"
|
||||
no-player-shop-type-selected: "&7You have to select a player shop type!"
|
||||
no-player-shops-via-command: "&7Player shops can only be created via the shop creation item!"
|
||||
shop-create-fail: "&7You cannot create a shopkeeper there."
|
||||
|
||||
type-new-name: "&aPlease type the shop's name into the chat.\n &aType a dash (-) to remove the name."
|
||||
|
|
Loading…
Reference in New Issue