Work on /npc shop

This commit is contained in:
fullwall 2022-07-21 23:13:51 +08:00
parent 805cd35f90
commit 8c004fc122
9 changed files with 165 additions and 24 deletions

View File

@ -360,9 +360,7 @@ public class Citizens extends JavaPlugin implements CitizensPlugin {
Bukkit.getPluginManager().registerEvents(new EventListen(storedRegistries), this);
if (Setting.NPC_COST.asDouble() > 0) {
setupEconomy();
}
setupEconomy();
registerCommands();
enableSubPlugins();

View File

@ -1684,6 +1684,23 @@ public class NPCCommands {
npc.getNavigator().setTarget(loc);
}
@Command(
aliases = { "npc" },
usage = "pickupitems (--set [true|false])",
desc = "Allow NPC to pick up items",
modifiers = { "pickupitems" },
min = 1,
max = 1,
permission = "citizens.npc.pickupitems")
public void pickupitems(CommandContext args, CommandSender sender, NPC npc) throws CommandException {
boolean pickup = !npc.data().get(NPC.Metadata.PICKUP_ITEMS, !npc.isProtected());
if (args.hasValueFlag("set")) {
pickup = Boolean.parseBoolean(args.getFlag("set").toLowerCase());
}
npc.data().set(NPC.Metadata.PICKUP_ITEMS, pickup);
Messaging.send(sender, pickup ? Messages.PICKUP_ITEMS_SET : Messages.PICKUP_ITEMS_UNSET, npc.getName());
}
@Command(
aliases = { "npc" },
usage = "panimate [animation]",

View File

@ -444,9 +444,10 @@ public class CitizensNPC extends AbstractNPC {
if (isLiving) {
NMS.setKnockbackResistance((LivingEntity) getEntity(), isProtected() ? 1D : 0D);
if (isProtected() && SUPPORT_PICKUP_ITEMS) {
if (SUPPORT_PICKUP_ITEMS) {
try {
((LivingEntity) getEntity()).setCanPickupItems(false);
((LivingEntity) getEntity())
.setCanPickupItems(data().get(NPC.Metadata.PICKUP_ITEMS, !isProtected()));
} catch (Throwable t) {
SUPPORT_PICKUP_ITEMS = false;
}

View File

@ -6,6 +6,7 @@ import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
@ -55,11 +56,11 @@ import net.milkbowl.vault.economy.Economy;
@TraitName("commandtrait")
public class CommandTrait extends Trait {
@Persist
@Persist(keyType = Integer.class)
@DelegatePersistence(NPCCommandPersister.class)
private final Map<String, NPCCommand> commands = Maps.newHashMap();
@Persist(reify = true)
private final Map<String, PlayerNPCCommand> cooldowns = Maps.newHashMap();
private final Map<Integer, NPCCommand> commands = Maps.newHashMap();
@Persist(keyType = UUID.class, reify = true)
private final Map<UUID, PlayerNPCCommand> cooldowns = Maps.newHashMap();
@Persist
private double cost = -1;
private final Map<String, Set<CommandTraitMessages>> executionErrors = Maps.newHashMap();
@ -82,7 +83,7 @@ public class CommandTrait extends Trait {
public int addCommand(NPCCommandBuilder builder) {
int id = getNewId();
commands.put(String.valueOf(id), builder.build(id));
commands.put(id, builder.build(id));
return id;
}
@ -228,7 +229,7 @@ public class CommandTrait extends Trait {
}
for (NPCCommand command : commandList) {
if (executionMode == ExecutionMode.SEQUENTIAL) {
PlayerNPCCommand info = cooldowns.get(player.getUniqueId().toString());
PlayerNPCCommand info = cooldowns.get(player.getUniqueId());
if (info != null && info.lastUsedHand != hand) {
info.lastUsedHand = hand;
info.lastUsedId = -1;
@ -252,10 +253,10 @@ public class CommandTrait extends Trait {
Runnable runnable = new Runnable() {
@Override
public void run() {
PlayerNPCCommand info = cooldowns.get(player.getUniqueId().toString());
PlayerNPCCommand info = cooldowns.get(player.getUniqueId());
if (info == null && (executionMode == ExecutionMode.SEQUENTIAL
|| PlayerNPCCommand.requiresTracking(command))) {
cooldowns.put(player.getUniqueId().toString(), info = new PlayerNPCCommand());
cooldowns.put(player.getUniqueId(), info = new PlayerNPCCommand());
}
if (info != null && !info.canUse(CommandTrait.this, player, command)) {
return;
@ -305,14 +306,14 @@ public class CommandTrait extends Trait {
private int getNewId() {
int i = 0;
while (commands.containsKey(String.valueOf(i))) {
while (commands.containsKey(i)) {
i++;
}
return i;
}
public boolean hasCommandId(int id) {
return commands.containsKey(String.valueOf(id));
return commands.containsKey(id);
}
public boolean isHideErrorMessages() {
@ -320,7 +321,7 @@ public class CommandTrait extends Trait {
}
public void removeCommandById(int id) {
commands.remove(String.valueOf(id));
commands.remove(id);
}
private void sendErrorMessage(Player player, CommandTraitMessages msg, Function<String, String> transform,

View File

@ -27,7 +27,7 @@ import net.citizensnpcs.api.util.DataKey;
@TraitName("scripttrait")
public class ScriptTrait extends Trait {
@Persist
public List<String> files = new ArrayList<String>();
private final List<String> files = new ArrayList<String>();
private final List<RunnableScript> runnableScripts = new ArrayList<RunnableScript>();
public ScriptTrait() {

View File

@ -31,6 +31,7 @@ import net.citizensnpcs.api.persistence.Persist;
import net.citizensnpcs.api.trait.Trait;
import net.citizensnpcs.api.trait.TraitName;
import net.citizensnpcs.api.util.Colorizer;
import net.citizensnpcs.trait.shop.NPCShopAction;
/**
* Shop trait for NPC GUI shops.
@ -50,7 +51,7 @@ public class ShopTrait extends Trait {
}
public static class NPCShop {
@Persist
@Persist(value = "")
private final String name;
@Persist(reify = true)
private final List<NPCShopPage> pages = Lists.newArrayList();
@ -123,7 +124,7 @@ public class ShopTrait extends Trait {
NPCShopPage sp = shop.getOrCreatePage(page);
for (int i = 0; i < ctx.getInventory().getSize(); i++) {
ctx.getSlot(i).clear();
NPCShopItem item = sp.items.get(i);
NPCShopItem item = sp.getItem(i);
final int idx = i;
ctx.getSlot(i).addClickHandler(evt -> {
ctx.clearSlots();
@ -137,9 +138,9 @@ public class ShopTrait extends Trait {
ctx.getMenu().transition(new NPCShopItemEditor(display, modified -> {
if (modified == null) {
sp.items.remove(idx);
sp.removeItem(idx);
} else {
sp.items.put(idx, modified);
sp.setItem(idx, modified);
}
}));
});
@ -229,9 +230,11 @@ public class ShopTrait extends Trait {
public static class NPCShopItem implements Cloneable {
@Persist
private int cost;
private List<NPCShopAction> cost;
@Persist
private ItemStack display;
@Persist
private List<NPCShopAction> result;
@Override
public NPCShopItem clone() {
@ -334,7 +337,7 @@ public class ShopTrait extends Trait {
public static class NPCShopPage {
@Persist("")
private int index;
@Persist(reify = true)
@Persist(keyType = Integer.class, reify = true)
private final Map<Integer, NPCShopItem> items = Maps.newHashMap();
@Persist
private String title;
@ -342,6 +345,18 @@ public class ShopTrait extends Trait {
public NPCShopPage(int page) {
this.index = page;
}
public NPCShopItem getItem(int idx) {
return items.get(idx);
}
public void removeItem(int idx) {
items.remove(idx);
}
public void setItem(int idx, NPCShopItem modified) {
items.put(idx, modified);
}
}
@Menu(title = "NPC Shop Page Editor", type = InventoryType.CHEST, dimensions = { 5, 9 })
@ -383,6 +398,6 @@ public class ShopTrait extends Trait {
@Persist(value = "npcShops", reify = true, namespace = "shopstrait")
private static Map<String, NPCShop> NPC_SHOPS = Maps.newHashMap();
@Persist(value = "namedShops", reify = true, namespace = "shopstrait")
@Persist(value = "globalShops", reify = true, namespace = "shopstrait")
private static Map<String, NPCShop> SHOPS = Maps.newHashMap();
}

View File

@ -0,0 +1,105 @@
package net.citizensnpcs.trait.shop;
import java.util.Arrays;
import java.util.List;
import org.bukkit.entity.HumanEntity;
import org.bukkit.inventory.ItemStack;
import com.google.common.collect.Lists;
import net.citizensnpcs.api.persistence.Persist;
import net.citizensnpcs.api.persistence.PersistenceLoader;
import net.citizensnpcs.api.persistence.PersisterRegistry;
public abstract class NPCShopAction implements Cloneable {
@Override
public NPCShopAction clone() {
try {
return (NPCShopAction) super.clone();
} catch (CloneNotSupportedException e) {
throw new Error(e);
}
}
public abstract boolean grant(HumanEntity entity);
public abstract boolean take(HumanEntity entity);
public static class ItemAction extends NPCShopAction {
@Persist
public List<ItemStack> items = Lists.newArrayList();
public ItemAction() {
}
public ItemAction(ItemStack... items) {
this(Arrays.asList(items));
}
public ItemAction(List<ItemStack> items) {
this.items = items;
}
@Override
public boolean grant(HumanEntity entity) {
return false;
}
@Override
public boolean take(HumanEntity entity) {
return false;
}
}
public static class MoneyAction extends NPCShopAction {
@Persist
public int money;
public MoneyAction() {
}
public MoneyAction(int money) {
this.money = money;
}
@Override
public boolean grant(HumanEntity entity) {
return false;
}
@Override
public boolean take(HumanEntity entity) {
return false;
}
}
public static class PermissionAction extends NPCShopAction {
@Persist
public List<String> permissions = Lists.newArrayList();
public PermissionAction() {
}
public PermissionAction(List<String> permissions) {
this.permissions = permissions;
}
@Override
public boolean grant(HumanEntity entity) {
return false;
}
@Override
public boolean take(HumanEntity entity) {
return false;
}
}
public static PersisterRegistry<NPCShopAction> REGISTRY = PersistenceLoader.createRegistry(NPCShopAction.class);
static {
REGISTRY.register("items", ItemAction.class);
REGISTRY.register("permissions", PermissionAction.class);
REGISTRY.register("money", MoneyAction.class);
}
}

View File

@ -275,6 +275,8 @@ public class Messages {
public static final String PATHFINDING_OPTIONS_USE_NEW_FINDER = "citizens.commands.npc.pathopt.use-new-finder";
public static final String PATHFINDING_RANGE_SET = "citizens.commands.npc.pathfindingrange.set";
public static final String PHANTOM_STATE_SET = "citizens.commands.npc.phantom.phantom-set";
public static final String PICKUP_ITEMS_SET = "citizens.commands.npc.pickupitems.set";
public static final String PICKUP_ITEMS_UNSET = "citizens.commands.npc.pickupitems.unset";
public static final String PIGLIN_DANCING_SET = "citizens.commands.npc.piglin.dancing-set";
public static final String PIGLIN_DANCING_UNSET = "citizens.commands.npc.piglin.dancing-unset";
public static final String PLAYER_NOT_FOUND_FOR_SPAWN = "citizens.commands.npc.create.no-player-for-spawn";

View File

@ -181,6 +181,8 @@ citizens.commands.npc.playerlist.added=Added [[{0}]] to the player list.
citizens.commands.npc.playerlist.removed=Removed [[{0}]] from the player list.
citizens.commands.npc.polarbear.rearing-set=[[{0}]] is now rearing.
citizens.commands.npc.polarbear.rearing-unset=[[{0}]] is no longer rearing.
citizens.commands.npc.pickupitems.set=[[{0}]] will now pickup items.
citizens.commands.npc.pickupitems.unset=[[{0}]] will no longer pickup items.
citizens.commands.npc.piglin.dancing-set=[[{0}]] is now dancing.
citizens.commands.npc.piglin.dancing-unset=[[{0}]] is no longer dancing.
citizens.commands.npc.pose.added=Pose added.