mirror of
https://github.com/CitizensDev/Citizens2.git
synced 2025-02-14 03:11:23 +01:00
Add simple /npc drops GUI and add NPC selection to /npc follow
This commit is contained in:
parent
65d02398fb
commit
9bbe9ae3c4
@ -93,6 +93,7 @@ import net.citizensnpcs.trait.CommandTrait.ItemRequirementGUI;
|
||||
import net.citizensnpcs.trait.CommandTrait.NPCCommandBuilder;
|
||||
import net.citizensnpcs.trait.Controllable;
|
||||
import net.citizensnpcs.trait.CurrentLocation;
|
||||
import net.citizensnpcs.trait.DropsTrait;
|
||||
import net.citizensnpcs.trait.EndermanTrait;
|
||||
import net.citizensnpcs.trait.FollowTrait;
|
||||
import net.citizensnpcs.trait.GameModeTrait;
|
||||
@ -310,7 +311,6 @@ public class NPCCommands {
|
||||
Messaging.sendTr(sender,
|
||||
npc.data().<Boolean> get(NPC.COLLIDABLE_METADATA) ? Messages.COLLIDABLE_SET : Messages.COLLIDABLE_UNSET,
|
||||
npc.getName());
|
||||
|
||||
}
|
||||
|
||||
@Command(
|
||||
@ -604,6 +604,20 @@ public class NPCCommands {
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "npc" },
|
||||
usage = "drops",
|
||||
desc = "Edit an NPC's drops",
|
||||
modifiers = { "drops" },
|
||||
min = 1,
|
||||
max = 1,
|
||||
permission = "citizens.npc.drops")
|
||||
@Requirements(ownership = true, selected = true)
|
||||
public void drops(CommandContext args, Player sender, NPC npc) throws CommandException {
|
||||
DropsTrait trait = npc.getOrAddTrait(DropsTrait.class);
|
||||
trait.displayEditor(sender);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "npc" },
|
||||
usage = "enderman -a[ngry]",
|
||||
@ -644,7 +658,7 @@ public class NPCCommands {
|
||||
|
||||
@Command(
|
||||
aliases = { "npc" },
|
||||
usage = "follow (player name) (-p[rotect])",
|
||||
usage = "follow (player name|NPC id) (-p[rotect])",
|
||||
desc = "Toggles NPC following you",
|
||||
flags = "p",
|
||||
modifiers = { "follow" },
|
||||
@ -657,9 +671,30 @@ public class NPCCommands {
|
||||
if (args.argsLength() > 1) {
|
||||
name = args.getString(1);
|
||||
}
|
||||
|
||||
OfflinePlayer player = Bukkit.getOfflinePlayer(name);
|
||||
if (player == null) {
|
||||
throw new CommandException();
|
||||
NPCCommandSelector.Callback callback = new NPCCommandSelector.Callback() {
|
||||
@Override
|
||||
public void run(NPC followingNPC) throws CommandException {
|
||||
if (followingNPC == null)
|
||||
throw new CommandException(Messages.COMMAND_MUST_HAVE_SELECTED);
|
||||
if (!(sender instanceof ConsoleCommandSender)
|
||||
&& !followingNPC.getOrAddTrait(Owner.class).isOwnedBy(sender))
|
||||
throw new CommandException(Messages.COMMAND_MUST_BE_OWNER);
|
||||
if (followingNPC.getEntity() instanceof Player) {
|
||||
boolean following = followingNPC.getOrAddTrait(FollowTrait.class)
|
||||
.toggle((Player) followingNPC.getEntity(), protect);
|
||||
Messaging.sendTr(sender, following ? Messages.FOLLOW_SET : Messages.FOLLOW_UNSET, npc.getName(),
|
||||
followingNPC.getName());
|
||||
} else {
|
||||
throw new CommandException();
|
||||
}
|
||||
}
|
||||
};
|
||||
NPCCommandSelector.startWithCallback(callback, CitizensAPI.getNPCRegistry(), sender, args,
|
||||
args.getString(1));
|
||||
return;
|
||||
}
|
||||
boolean following = npc.getOrAddTrait(FollowTrait.class).toggle(player, protect);
|
||||
Messaging.sendTr(sender, following ? Messages.FOLLOW_SET : Messages.FOLLOW_UNSET, npc.getName(),
|
||||
|
@ -28,6 +28,7 @@ import net.citizensnpcs.trait.ClickRedirectTrait;
|
||||
import net.citizensnpcs.trait.CommandTrait;
|
||||
import net.citizensnpcs.trait.Controllable;
|
||||
import net.citizensnpcs.trait.CurrentLocation;
|
||||
import net.citizensnpcs.trait.DropsTrait;
|
||||
import net.citizensnpcs.trait.EndermanTrait;
|
||||
import net.citizensnpcs.trait.FollowTrait;
|
||||
import net.citizensnpcs.trait.GameModeTrait;
|
||||
@ -66,6 +67,7 @@ public class CitizensTraitFactory implements TraitFactory {
|
||||
registerTrait(TraitInfo.create(CommandTrait.class));
|
||||
registerTrait(TraitInfo.create(Controllable.class));
|
||||
registerTrait(TraitInfo.create(CurrentLocation.class));
|
||||
registerTrait(TraitInfo.create(DropsTrait.class));
|
||||
registerTrait(TraitInfo.create(EndermanTrait.class));
|
||||
registerTrait(TraitInfo.create(Equipment.class));
|
||||
registerTrait(TraitInfo.create(FollowTrait.class));
|
||||
|
@ -37,7 +37,6 @@ import net.citizensnpcs.api.gui.MenuContext;
|
||||
import net.citizensnpcs.api.npc.NPC;
|
||||
import net.citizensnpcs.api.persistence.DelegatePersistence;
|
||||
import net.citizensnpcs.api.persistence.Persist;
|
||||
import net.citizensnpcs.api.persistence.PersistenceLoader;
|
||||
import net.citizensnpcs.api.persistence.Persister;
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
import net.citizensnpcs.api.trait.TraitName;
|
||||
@ -55,8 +54,7 @@ public class CommandTrait extends Trait {
|
||||
@Persist
|
||||
@DelegatePersistence(NPCCommandPersister.class)
|
||||
private final Map<String, NPCCommand> commands = Maps.newHashMap();
|
||||
@Persist
|
||||
@DelegatePersistence(PlayerNPCCommandPersister.class)
|
||||
@Persist(reify = true)
|
||||
private final Map<String, PlayerNPCCommand> cooldowns = Maps.newHashMap();
|
||||
@Persist
|
||||
private double cost = -1;
|
||||
@ -599,19 +597,4 @@ public class CommandTrait extends Trait {
|
||||
return command.cooldown > 0 || command.n > 0 || (command.perms != null && command.perms.size() > 0);
|
||||
}
|
||||
}
|
||||
|
||||
private static class PlayerNPCCommandPersister implements Persister<PlayerNPCCommand> {
|
||||
public PlayerNPCCommandPersister() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlayerNPCCommand create(DataKey root) {
|
||||
return PersistenceLoader.load(PlayerNPCCommand.class, root);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(PlayerNPCCommand instance, DataKey root) {
|
||||
PersistenceLoader.save(instance, root);
|
||||
}
|
||||
}
|
||||
}
|
146
main/src/main/java/net/citizensnpcs/trait/DropsTrait.java
Normal file
146
main/src/main/java/net/citizensnpcs/trait/DropsTrait.java
Normal file
@ -0,0 +1,146 @@
|
||||
package net.citizensnpcs.trait;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.HumanEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.inventory.InventoryType;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import net.citizensnpcs.api.CitizensAPI;
|
||||
import net.citizensnpcs.api.event.NPCDeathEvent;
|
||||
import net.citizensnpcs.api.gui.InventoryMenu;
|
||||
import net.citizensnpcs.api.gui.InventoryMenuPage;
|
||||
import net.citizensnpcs.api.gui.InventoryMenuSlot;
|
||||
import net.citizensnpcs.api.gui.Menu;
|
||||
import net.citizensnpcs.api.gui.MenuContext;
|
||||
import net.citizensnpcs.api.gui.PercentageSlotHandler;
|
||||
import net.citizensnpcs.api.persistence.Persist;
|
||||
import net.citizensnpcs.api.trait.Trait;
|
||||
import net.citizensnpcs.api.trait.TraitName;
|
||||
import net.citizensnpcs.util.Util;
|
||||
|
||||
@TraitName("dropstrait")
|
||||
public class DropsTrait extends Trait {
|
||||
@Persist(reify = true)
|
||||
private List<ItemDrop> drops = Lists.newArrayList();
|
||||
|
||||
public DropsTrait() {
|
||||
super("dropstrait");
|
||||
}
|
||||
|
||||
public void displayEditor(Player sender) {
|
||||
InventoryMenu.createSelfRegistered(new DropsGUI(this)).present(sender);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onNPCDeath(NPCDeathEvent event) {
|
||||
if (!event.getNPC().equals(npc))
|
||||
return;
|
||||
Random random = Util.getFastRandom();
|
||||
for (ItemDrop drop : drops) {
|
||||
if (random.nextDouble() < drop.chance) {
|
||||
event.getDrops().add(drop.drop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Menu(title = "Add items for drops", type = InventoryType.CHEST, dimensions = { 5, 9 })
|
||||
public static class DropsGUI extends InventoryMenuPage {
|
||||
private final Map<Integer, Double> chances = Maps.newHashMap();
|
||||
private Inventory inventory;
|
||||
private int taskId;
|
||||
private DropsTrait trait;
|
||||
|
||||
private DropsGUI() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public DropsGUI(DropsTrait trait) {
|
||||
this.trait = trait;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialise(MenuContext ctx) {
|
||||
this.taskId = Bukkit.getScheduler().scheduleSyncRepeatingTask(CitizensAPI.getPlugin(), this, 0, 1);
|
||||
this.inventory = ctx.getInventory();
|
||||
int k = 0;
|
||||
for (int i = 1; i < 5; i += 2) {
|
||||
for (int j = 0; j < 9; j++) {
|
||||
int islot = (i - 1) * 9 + j;
|
||||
|
||||
ItemDrop drop;
|
||||
int chance = 100;
|
||||
if (k < trait.drops.size()) {
|
||||
drop = trait.drops.get(k++);
|
||||
chance = (int) Math.floor(drop.chance * 100.0);
|
||||
chances.put(islot, drop.chance);
|
||||
ctx.getInventory().setItem(islot, drop.drop.clone());
|
||||
}
|
||||
InventoryMenuSlot slot = ctx.getSlot(i * 9 + j);
|
||||
slot.setItemStack(new ItemStack(Material.GLASS_PANE), "Drop chance <e>" + chance + "%");
|
||||
slot.addClickHandler(new PercentageSlotHandler((pct) -> {
|
||||
if (chances.containsKey(islot)) {
|
||||
chances.put(islot, pct / 100.0);
|
||||
}
|
||||
return "Drop chance <e>" + pct + "%";
|
||||
}, chance));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(InventoryMenuSlot slot, InventoryClickEvent event) {
|
||||
if (event.getAction().name().contains("PICKUP")) {
|
||||
chances.remove(event.getSlot());
|
||||
} else if (event.getAction().name().contains("PLACE")) {
|
||||
chances.putIfAbsent(event.getSlot(), 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose(HumanEntity player) {
|
||||
Bukkit.getScheduler().cancelTask(taskId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
List<ItemDrop> drops = Lists.newArrayList();
|
||||
for (int i = 0; i < 5; i += 2) {
|
||||
for (int j = 0; j < 9; j++) {
|
||||
int slot = i * 9 + j;
|
||||
ItemStack stack = inventory.getItem(slot);
|
||||
if (stack == null || stack.getType() == Material.AIR)
|
||||
continue;
|
||||
drops.add(new ItemDrop(stack, chances.getOrDefault(slot, 1.0)));
|
||||
}
|
||||
}
|
||||
this.trait.drops = drops;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ItemDrop {
|
||||
@Persist
|
||||
double chance;
|
||||
@Persist
|
||||
ItemStack drop;
|
||||
|
||||
public ItemDrop() {
|
||||
}
|
||||
|
||||
public ItemDrop(ItemStack drop, double chance) {
|
||||
this.drop = drop;
|
||||
this.chance = chance;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user