initial text editing using Conversations API

This commit is contained in:
aPunch 2012-03-02 14:42:34 -06:00
parent de7ab2b109
commit 8f0af02292
15 changed files with 311 additions and 25 deletions

View File

@ -38,6 +38,7 @@ import net.citizensnpcs.command.exception.WrappedCommandException;
import net.citizensnpcs.editor.Editor;
import net.citizensnpcs.npc.CitizensNPCManager;
import net.citizensnpcs.trait.LookClose;
import net.citizensnpcs.trait.text.Text;
import net.citizensnpcs.trait.waypoint.Waypoints;
import net.citizensnpcs.util.Messaging;
import net.citizensnpcs.util.Metrics;
@ -63,7 +64,8 @@ public class Citizens extends JavaPlugin {
private volatile CitizensNPCManager npcManager;
private Storage saves;
private final InstanceFactory<Trait> traitManager = DefaultInstanceFactory.create(Owner.class, Spawned.class,
LookClose.class, SpawnLocation.class, Inventory.class, MobType.class, Waypoints.class, Equipment.class);
LookClose.class, SpawnLocation.class, Inventory.class, MobType.class, Waypoints.class, Equipment.class,
Text.class);
public InstanceFactory<Character> getCharacterManager() {
return characterManager;

View File

@ -112,6 +112,7 @@ public class EventListen implements Listener {
return;
}
}
// TODO NPC text
if (npc.getCharacter() != null)
npc.getCharacter().onRightClick(npc, player);
}

View File

@ -10,7 +10,7 @@ import net.citizensnpcs.command.CommandContext;
import net.citizensnpcs.command.Requirements;
import net.citizensnpcs.editor.Editor;
import net.citizensnpcs.editor.EquipmentEditor;
import net.citizensnpcs.editor.TextEditor;
import net.citizensnpcs.trait.text.Text;
import net.citizensnpcs.trait.waypoint.Waypoints;
@Requirements(selected = true, ownership = true)
@ -55,6 +55,6 @@ public class EditorCommands {
max = 1,
permission = "npc.edit.text")
public void text(CommandContext args, Player player, NPC npc) {
Editor.enterOrLeave(player, new TextEditor());
Editor.enterOrLeave(player, npc.getTrait(Text.class).getEditor(player));
}
}

View File

@ -35,7 +35,7 @@ public class EquipmentEditor extends Editor {
@Override
public void end() {
Messaging.send(player, "<a>Exited equipment editor.");
Messaging.send(player, "<a>Exited the equipment editor.");
}
@EventHandler
@ -100,17 +100,15 @@ public class EquipmentEditor extends Editor {
Messaging.send(player, "<e>" + npc.getName() + " <a>had all of its items removed.");
}
// Now edit the equipment based on the slot
if (trait.get(slot) != null && trait.get(slot).getType() != Material.AIR) {
if (trait.get(slot) != null && trait.get(slot).getType() != Material.AIR)
player.getWorld().dropItemNaturally(npc.getBukkitEntity().getLocation(), trait.get(slot));
}
ItemStack set = hand;
if (set != null && set.getType() != Material.AIR) {
if (hand.getAmount() > 1) {
if (hand.getAmount() > 1)
hand.setAmount(hand.getAmount() - 1);
} else {
else
hand = null;
}
player.setItemInHand(hand);
set.setAmount(1);
}

View File

@ -1,12 +0,0 @@
package net.citizensnpcs.editor;
public class TextEditor extends Editor {
@Override
public void begin() {
}
@Override
public void end() {
}
}

View File

@ -1,6 +1,5 @@
package net.citizensnpcs.trait;
import net.citizensnpcs.Toggleable;
import net.citizensnpcs.api.exception.NPCLoadException;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.trait.SaveId;

View File

@ -1,4 +1,4 @@
package net.citizensnpcs;
package net.citizensnpcs.trait;
/**
* Represents a two-state entity which can be toggled on and off.

View File

@ -0,0 +1,120 @@
package net.citizensnpcs.trait.text;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import org.bukkit.Bukkit;
import org.bukkit.conversations.ConversationFactory;
import org.bukkit.entity.Player;
import net.citizensnpcs.Citizens;
import net.citizensnpcs.api.exception.NPCLoadException;
import net.citizensnpcs.api.npc.NPC;
import net.citizensnpcs.api.trait.SaveId;
import net.citizensnpcs.api.trait.Trait;
import net.citizensnpcs.api.util.DataKey;
import net.citizensnpcs.editor.Editor;
import net.citizensnpcs.npc.CitizensNPC;
import net.citizensnpcs.trait.Toggleable;
import net.citizensnpcs.trait.text.prompt.StartPrompt;
import net.citizensnpcs.util.Messaging;
import net.citizensnpcs.util.Paginator;
import net.minecraft.server.EntityHuman;
import net.minecraft.server.EntityLiving;
@SaveId("text")
public class Text extends Trait implements Runnable, Toggleable {
private final Citizens plugin;
private final NPC npc;
private final List<String> text = new ArrayList<String>();
private boolean talkClose;
public Text(NPC npc) {
this.npc = npc;
plugin = (Citizens) Bukkit.getPluginManager().getPlugin("Citizens");
}
@Override
public void load(DataKey key) throws NPCLoadException {
for (DataKey sub : key.getIntegerSubKeys())
text.add(sub.getString(""));
if (key.keyExists("talk-close"))
talkClose = key.getBoolean("talk-close");
}
@Override
public void save(DataKey key) {
key.setBoolean("talk-close", talkClose);
for (int i = 0; i < text.size(); i++)
key.setString(String.valueOf(i), text.get(i));
}
@Override
public void toggle() {
talkClose = !talkClose;
}
@Override
public void run() {
EntityHuman search = null;
EntityLiving handle = ((CitizensNPC) npc).getHandle();
if ((search = handle.world.findNearbyPlayer(handle, 5)) != null && talkClose)
sendRandomText((Player) search.getBukkitEntity());
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("Text{talk-close=" + talkClose + ",text=");
for (String line : text)
builder.append(line + ",");
builder.append("}");
return builder.toString();
}
public Editor getEditor(final Player player) {
final StartPrompt startPrompt = new StartPrompt(this);
return new Editor() {
@Override
public void begin() {
Messaging.send(player, "<b>Entered the text editor!");
new ConversationFactory(plugin).withFirstPrompt(startPrompt).withEscapeSequence("/npc text")
.buildConversation(player).begin();
}
@Override
public void end() {
Messaging.send(player, "<a>Exited the text editor.");
}
};
}
public void add(String string) {
text.add(string);
}
public void remove(int index) {
text.remove(index);
}
public void edit(int index, String newText) {
text.set(index, newText);
}
public boolean sendPage(Player player, int page) {
Paginator paginator = new Paginator();
paginator.setHeaderText(npc.getName() + "'s Text Entries");
for (String line : text)
paginator.addLine(line);
return paginator.sendPage(player, page);
}
private void sendRandomText(Player player) {
npc.chat(player, text.get(new Random().nextInt(text.size())));
}
}

View File

@ -0,0 +1,38 @@
package net.citizensnpcs.trait.text.prompt;
import net.citizensnpcs.trait.text.Text;
import net.citizensnpcs.util.Messaging;
import net.citizensnpcs.util.StringHelper;
import org.bukkit.conversations.ConversationContext;
import org.bukkit.conversations.Prompt;
import org.bukkit.conversations.StringPrompt;
import org.bukkit.entity.Player;
public class StartPrompt extends StringPrompt {
private Text text;
public StartPrompt(Text text) {
this.text = text;
}
@Override
public Prompt acceptInput(ConversationContext context, String string) {
if (string.equalsIgnoreCase("add"))
return new TextAddPrompt(text);
else if (string.equalsIgnoreCase("edit"))
return new TextEditSelectIndexPrompt(text);
else if (string.equalsIgnoreCase("remove"))
return new TextRemovePrompt(text);
else {
Messaging.sendError((Player) context.getForWhom(), "Invalid edit type.");
return new StartPrompt(text);
}
}
@Override
public String getPromptText(ConversationContext context) {
return StringHelper
.parseColors("<a>Type <e>add <a>to add an entry, <e>edit <a>to edit entries, and <e>remove <a>to remove entries.");
}
}

View File

@ -0,0 +1,28 @@
package net.citizensnpcs.trait.text.prompt;
import net.citizensnpcs.trait.text.Text;
import net.citizensnpcs.util.StringHelper;
import org.bukkit.conversations.ConversationContext;
import org.bukkit.conversations.Prompt;
import org.bukkit.conversations.StringPrompt;
public class TextAddPrompt extends StringPrompt {
private Text text;
public TextAddPrompt(Text text) {
this.text = text;
}
@Override
public Prompt acceptInput(ConversationContext context, String string) {
text.add(string);
context.getForWhom().sendRawMessage(StringHelper.parseColors("<e>Added <a>the entry <e>" + string + "."));
return new StartPrompt(text);
}
@Override
public String getPromptText(ConversationContext context) {
return "Enter text to add to the NPC.";
}
}

View File

@ -0,0 +1,32 @@
package net.citizensnpcs.trait.text.prompt;
import net.citizensnpcs.trait.text.Text;
import net.citizensnpcs.util.Messaging;
import net.citizensnpcs.util.StringHelper;
import org.bukkit.conversations.ConversationContext;
import org.bukkit.conversations.Prompt;
import org.bukkit.conversations.StringPrompt;
import org.bukkit.entity.Player;
public class TextEditPrompt extends StringPrompt {
private Text text;
public TextEditPrompt(Text text) {
this.text = text;
}
@Override
public Prompt acceptInput(ConversationContext context, String string) {
text.edit((Integer) context.getSessionData("index"), string);
Messaging.send((Player) context.getForWhom(), "<a>Changed entry at index <e>" + context.getSessionData("index")
+ " <a>to <e>" + string + "<a>.");
return new StartPrompt(text);
}
@Override
public String getPromptText(ConversationContext context) {
return StringHelper.parseColors("<a>Enter text to change the entry at the index <e>"
+ context.getSessionData("index") + "<a>.");
}
}

View File

@ -0,0 +1,39 @@
package net.citizensnpcs.trait.text.prompt;
import net.citizensnpcs.trait.text.Text;
import net.citizensnpcs.util.Messaging;
import net.citizensnpcs.util.StringHelper;
import org.bukkit.ChatColor;
import org.bukkit.conversations.ConversationContext;
import org.bukkit.conversations.NumericPrompt;
import org.bukkit.conversations.Prompt;
import org.bukkit.entity.Player;
public class TextEditSelectIndexPrompt extends NumericPrompt {
private Text text;
public TextEditSelectIndexPrompt(Text text) {
this.text = text;
}
@Override
public Prompt acceptValidatedInput(ConversationContext context, Number number) {
context.setSessionData("index", number.intValue());
Messaging.send((Player) context.getForWhom(), "<a>Now <e>editing <a>the entry at index <e>" + number.intValue()
+ "<a>. Enter text to replace the entry with.");
return new TextEditPrompt(text);
}
@Override
public String getFailedValidationText(ConversationContext context, String invalidInput) {
return ChatColor.RED + invalidInput + " is not a valid index!";
}
@Override
public String getPromptText(ConversationContext context) {
Player player = (Player) context.getForWhom();
text.sendPage(player, 1);
return StringHelper.parseColors("<a>Enter the index of the entry you wish to edit.");
}
}

View File

@ -0,0 +1,39 @@
package net.citizensnpcs.trait.text.prompt;
import net.citizensnpcs.trait.text.Text;
import net.citizensnpcs.util.Messaging;
import net.citizensnpcs.util.StringHelper;
import org.bukkit.ChatColor;
import org.bukkit.conversations.ConversationContext;
import org.bukkit.conversations.NumericPrompt;
import org.bukkit.conversations.Prompt;
import org.bukkit.entity.Player;
public class TextRemovePrompt extends NumericPrompt {
private Text text;
public TextRemovePrompt(Text text) {
this.text = text;
}
@Override
public Prompt acceptValidatedInput(ConversationContext context, Number number) {
int index = number.intValue();
text.remove(index);
Messaging.send((Player) context.getForWhom(), "<e>Removed <a>entry at index <e>" + index + "<a>.");
return new StartPrompt(text);
}
@Override
public String getFailedValidationText(ConversationContext context, String invalidInput) {
return ChatColor.RED + invalidInput + " is not a valid index!";
}
@Override
public String getPromptText(ConversationContext context) {
Player player = (Player) context.getForWhom();
text.sendPage(player, 1);
return StringHelper.parseColors("<a>Enter the index of the entry you wish to remove.");
}
}

View File

@ -25,6 +25,7 @@ public class LinearWaypointProvider implements WaypointProvider, Iterable<Waypoi
@Override
public Editor createEditor(final Player player) {
return new Editor() {
@Override
public void begin() {
player.sendMessage(ChatColor.AQUA + "Entered the linear waypoint editor!");
@ -49,8 +50,8 @@ public class LinearWaypointProvider implements WaypointProvider, Iterable<Waypoi
at.getBlockX(), at.getBlockY(), at.getBlockZ()));
} else if (waypoints.size() > 0) {
waypoints.remove(waypoints.size() - 1);
Messaging.send(player,
String.format("<e>Removed<a> a waypoint (<e>%d<a> remaining)", waypoints.size()));
Messaging.send(player, String.format("<e>Removed<a> a waypoint (<e>%d<a> remaining)", waypoints
.size()));
}
}
};

View File

@ -8,6 +8,7 @@ import net.citizensnpcs.editor.Editor;
import org.bukkit.entity.Player;
public interface WaypointProvider {
/**
* Creates an {@link Editor} with the given {@link Player}.
*