Version 1.5.1:

* Add toggleable Shopkeepers support
* Made Citizens support toggleable

To-do:
* Add enchantments, data, etc. to ingredients and result
* Add config editor GUI in-game
This commit is contained in:
PretzelJohn 2022-01-21 20:56:44 -05:00
parent 5cc49188a7
commit afacf4adc8
10 changed files with 46 additions and 26 deletions

View File

@ -51,6 +51,14 @@
<td><code>database.useSSL:</code></td>
<td>If your MySQL database can use SSL connections, set this to <code>true</code>!</td>
</tr>
<tr>
<td><code>IgnoreCitizens:</code></td>
<td>Whether to ignore Citizens NPCs from the Citizens plugin. If set to true, Citizens NPCs won't be affected by this plugin.</td>
</tr>
<tr>
<td><code>IgnoreShopkeepers:</code></td>
<td>Whether to ignore Shopkeepers NPCs from the Shopkeepers plugin. If set to true, Shopkeepers NPCs won't be affected by this plugin.</td>
</tr>
<tr>
<td><code>DisableTrading:</code></td>
<td>Whether to disable all villager trading for all worlds, some worlds, or no worlds.<br/><strong>Options:</strong>

View File

@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.pretzel.dev</groupId>
<artifactId>VillagerTradeLimiter</artifactId>
<version>1.5.0</version>
<version>1.5.1</version>
<properties>
<java.version>1.8</java.version>

View File

@ -8,8 +8,8 @@ import java.io.FileWriter;
import java.io.Reader;
import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Villager;
import net.md_5.bungee.api.ChatColor;
@ -66,21 +66,21 @@ public class Util {
}
/**
* Checks whether a player is a Citizens NPC or not
* @param player The player to check
* @return True if the player is an NPC, false otherwise
* Checks whether an entity is a Citizens NPC or not
* @param entity The entity to check
* @return True if the entity is an NPC, false otherwise
*/
public static boolean isNPC(Player player) {
return player.hasMetadata("NPC");
public static boolean isNPC(Entity entity) {
return entity.hasMetadata("NPC");
}
/**
* Returns whether a villager is a Citizens NPC or not
* @param villager The villager to check
* @return True if the villager is an NPC, false otherwise
* Returns whether an entity is a shopkeeper NPC or not
* @param entity The villager to check
* @return True if the villager is a shopkeeper, false otherwise
*/
public static boolean isNPC(Villager villager) {
return villager.hasMetadata("NPC");
public static boolean isShopkeeper(Entity entity) {
return entity.hasMetadata("shopkeeper");
}
/**

View File

@ -3,7 +3,6 @@ package com.pretzel.dev.villagertradelimiter.listeners;
import com.pretzel.dev.villagertradelimiter.VillagerTradeLimiter;
import com.pretzel.dev.villagertradelimiter.data.Cooldown;
import com.pretzel.dev.villagertradelimiter.data.PlayerData;
import com.pretzel.dev.villagertradelimiter.lib.Util;
import com.pretzel.dev.villagertradelimiter.settings.Settings;
import com.pretzel.dev.villagertradelimiter.wrappers.VillagerWrapper;
import org.bukkit.Bukkit;
@ -44,7 +43,7 @@ public class InventoryListener implements Listener {
if(!(event.getInventory().getHolder() instanceof Villager)) return;
if(!(event.getPlayer() instanceof Player)) return;
final Player player = (Player)event.getPlayer();
if(Util.isNPC(player)) return;
if(settings.shouldSkipNPC(player) || settings.shouldSkipNPC((Villager)event.getInventory().getHolder())) return; //Skips NPCs
//Reset the villager's NBT data when a player is finished trading
final PlayerData playerData = instance.getPlayerData().get(player.getUniqueId());
@ -64,7 +63,7 @@ public class InventoryListener implements Listener {
if(!(event.getWhoClicked() instanceof Player)) return;
if(event.getRawSlot() != 2) return;
final Player player = (Player)event.getWhoClicked();
if(Util.isNPC(player)) return;
if(settings.shouldSkipNPC(player) || settings.shouldSkipNPC((Villager)event.getInventory().getHolder())) return; //Skips NPCs
//Get the items involved in the trade
final ItemStack result = event.getCurrentItem();

View File

@ -3,7 +3,6 @@ package com.pretzel.dev.villagertradelimiter.listeners;
import com.pretzel.dev.villagertradelimiter.VillagerTradeLimiter;
import com.pretzel.dev.villagertradelimiter.data.Cooldown;
import com.pretzel.dev.villagertradelimiter.data.PlayerData;
import com.pretzel.dev.villagertradelimiter.lib.Util;
import com.pretzel.dev.villagertradelimiter.settings.Settings;
import com.pretzel.dev.villagertradelimiter.wrappers.*;
import org.bukkit.OfflinePlayer;
@ -37,8 +36,9 @@ public class PlayerListener implements Listener {
@EventHandler
public void onPlayerBeginTrading(final PlayerInteractEntityEvent event) {
if(!(event.getRightClicked() instanceof Villager)) return;
final Player player = event.getPlayer();
final Villager villager = (Villager)event.getRightClicked();
if(Util.isNPC(villager)) return; //Skips NPCs
if(settings.shouldSkipNPC(event.getPlayer()) || settings.shouldSkipNPC(villager)) return; //Skips NPCs
if(villager.getProfession() == Villager.Profession.NONE || villager.getProfession() == Villager.Profession.NITWIT) return; //Skips non-trading villagers
if(villager.getRecipeCount() == 0) return; //Skips non-trading villagers
@ -63,13 +63,13 @@ public class PlayerListener implements Listener {
//Cancel the original event, and open the adjusted trade view
event.setCancelled(true);
final Player player = event.getPlayer();
if(!instance.getPlayerData().containsKey(player.getUniqueId())) {
instance.getPlayerData().put(player.getUniqueId(), new PlayerData());
}
if(!instance.getPlayerData().containsKey(villager.getUniqueId())) {
instance.getPlayerData().put(villager.getUniqueId(), new PlayerData());
}
this.see(villager, player, player);
}
@ -83,7 +83,8 @@ public class PlayerListener implements Listener {
//Wraps the villager and player into wrapper classes
final VillagerWrapper villagerWrapper = new VillagerWrapper(villager);
final PlayerWrapper otherWrapper = new PlayerWrapper(other);
if(Util.isNPC(villager) || Util.isNPC(player) || otherWrapper.isNPC()) return; //Skips NPCs
final Player otherPlayer = otherWrapper.getPlayer();
if(settings.shouldSkipNPC(player) || settings.shouldSkipNPC(villager) || otherPlayer == null || settings.shouldSkipNPC(otherPlayer)) return; //Skips NPCs
final PlayerData playerData = instance.getPlayerData().get(other.getUniqueId());
if(playerData != null) playerData.setTradingVillager(villagerWrapper);

View File

@ -3,7 +3,6 @@ package com.pretzel.dev.villagertradelimiter.listeners;
import com.pretzel.dev.villagertradelimiter.VillagerTradeLimiter;
import com.pretzel.dev.villagertradelimiter.data.Cooldown;
import com.pretzel.dev.villagertradelimiter.data.PlayerData;
import com.pretzel.dev.villagertradelimiter.lib.Util;
import com.pretzel.dev.villagertradelimiter.settings.Settings;
import org.bukkit.entity.Villager;
import org.bukkit.event.EventHandler;
@ -33,7 +32,8 @@ public class VillagerListener implements Listener {
@EventHandler
public void onVillagerRestock(final VillagerReplenishTradeEvent event) {
if(!(event.getEntity() instanceof Villager)) return;
if(Util.isNPC((Villager) event.getEntity())) return;
final Villager villager = (Villager)event.getEntity();
if(settings.shouldSkipNPC(villager)) return; //Skips NPCs
//Get the items involved in the restock
final MerchantRecipe recipe = event.getRecipe();
@ -43,7 +43,7 @@ public class VillagerListener implements Listener {
final String type = settings.getType(result, ingredient1, ingredient2);
//Get the villager's data container
final UUID uuid = event.getEntity().getUniqueId();
final UUID uuid = villager.getUniqueId();
final PlayerData villagerData = instance.getPlayerData().get(uuid);
if(villagerData == null) return;

View File

@ -8,6 +8,7 @@ import org.bukkit.NamespacedKey;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.enchantments.EnchantmentWrapper;
import org.bukkit.entity.Entity;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
@ -17,6 +18,16 @@ public class Settings {
/** @param instance The instance of VillagerTradeLimiter.java */
public Settings(final VillagerTradeLimiter instance) { this.instance = instance; }
/**
* @param entity The entity to check the NPC status of
* @return True if the entity is an NPC and config is set to ignore NPCs
*/
public boolean shouldSkipNPC(final Entity entity) {
if(entity == null) return true;
if(instance.getCfg().getBoolean("IgnoreCitizens", true) && Util.isNPC(entity)) return true;
return instance.getCfg().getBoolean("IgnoreShopkeepers", true) && Util.isShopkeeper(entity);
}
/**
* @param recipe The wrapped recipe to fetch any overrides for
* @param key The key where the fetched value is stored in config.yml (e.g, DisableTrading)

View File

@ -12,9 +12,6 @@ public class PlayerWrapper {
/** @param player The offline player that this wrapper wraps */
public PlayerWrapper(final OfflinePlayer player) { this.player = player; }
/** @return Whether this player is an NPC or not */
public boolean isNPC() { return (player.isOnline() && Util.isNPC((Player)player)); }
/**
* @param isOld Whether the server is older than 1.16 or not. Minecraft changed how UUID's are represented in 1.16
* @return A string representation of the player's UUID, for use when matching the player's UUID to a gossip's target UUID

View File

@ -19,6 +19,10 @@ database:
encoding: utf8
useSSL: false
# Ignore Citizens NPCs, and/or Shopkeepers NPCs if true
IgnoreCitizens: true
IgnoreShopkeepers: true
# Add world names for worlds that you want to completely disable ALL villager trading. Set to [] to disable this feature.
DisableTrading:
- world_nether

View File

@ -1,7 +1,7 @@
name: VillagerTradeLimiter
author: PretzelJohn
main: com.pretzel.dev.villagertradelimiter.VillagerTradeLimiter
version: 1.5.0
version: 1.5.1
api-version: 1.14
commands: