Repository reorganisation
Unified kotlin and java into just src/main Unified the rs09 and core packages Took all content out of the core package, and placed it into the new content package Reorganised all source code relating to content to be easier to find and explore
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
package core.game.dialogue;
|
||||
|
||||
import content.global.skill.slayer.SlayerManager;
|
||||
import core.cache.def.impl.ItemDefinition;
|
||||
import core.game.interaction.OptionHandler;
|
||||
import core.game.node.Node;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.plugin.Initializable;
|
||||
import core.plugin.Plugin;
|
||||
|
||||
/**
|
||||
* Represents the plugin used to handle the enchanted gem related to slayer.
|
||||
* @author 'Vexia
|
||||
* @version 1.0
|
||||
*/
|
||||
@Initializable
|
||||
public final class ActivateEnchantedGem extends OptionHandler {
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ActivateEnchantedGem} {@Code Object}.
|
||||
*/
|
||||
public ActivateEnchantedGem() {
|
||||
/**
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(Player player, Node node, String option) {
|
||||
if (!SlayerManager.getInstance(player).hasStarted()) {
|
||||
player.getPacketDispatch().sendMessage("You try to activate the gem...");
|
||||
return true;
|
||||
}
|
||||
player.getDialogueInterpreter().open(77777);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWalk() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Plugin<Object> newInstance(Object arg) throws Throwable {
|
||||
ItemDefinition.forId(4155).getHandlers().put("option:activate", this);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package core.game.dialogue;
|
||||
|
||||
import core.game.node.entity.player.Player;
|
||||
|
||||
/**
|
||||
* A dialogue reward.
|
||||
* @author Vexia
|
||||
*/
|
||||
public interface DialogueAction {
|
||||
|
||||
/**
|
||||
* Handles a dialogue click.
|
||||
* @param player the player.
|
||||
* @param buttonId the buttonId.
|
||||
*/
|
||||
public void handle(Player player, int buttonId);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
package core.game.dialogue
|
||||
import core.game.node.entity.player.Player
|
||||
import core.tools.END_DIALOGUE
|
||||
|
||||
abstract class DialogueBuilderFile : core.game.dialogue.DialogueFile() {
|
||||
var data: ArrayList<core.game.dialogue.DialogueClause> = ArrayList()
|
||||
//var stages: ArrayList<Int> = ArrayList()
|
||||
abstract fun create(b: core.game.dialogue.DialogueBuilder)
|
||||
init {
|
||||
create(core.game.dialogue.DialogueBuilder(this))
|
||||
}
|
||||
override fun handle(componentID: Int, buttonID: Int) {
|
||||
for((i, clause) in data.iterator().withIndex()) {
|
||||
if(clause.predicate(player!!)) {
|
||||
stage = clause.handle(this, componentID, buttonID, stage)
|
||||
if(stage == END_DIALOGUE) {
|
||||
end()
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface DialogueNode {
|
||||
fun handle(df: core.game.dialogue.DialogueFile, componentID: Int, buttonID: Int, stage: Int): Int
|
||||
}
|
||||
|
||||
class NpcLNode(val value: String): core.game.dialogue.DialogueNode {
|
||||
override fun handle(df: core.game.dialogue.DialogueFile, componentID: Int, buttonID: Int, stage: Int): Int {
|
||||
df.npcl(value)
|
||||
return stage + 1
|
||||
}
|
||||
}
|
||||
class NpcNode(val values: Array<String>): core.game.dialogue.DialogueNode {
|
||||
override fun handle(df: core.game.dialogue.DialogueFile, componentID: Int, buttonID: Int, stage: Int): Int {
|
||||
df.npc(*values)
|
||||
return stage + 1
|
||||
}
|
||||
}
|
||||
class PlayerLNode(val value: String): core.game.dialogue.DialogueNode {
|
||||
override fun handle(df: core.game.dialogue.DialogueFile, componentID: Int, buttonID: Int, stage: Int): Int {
|
||||
df.playerl(value)
|
||||
return stage + 1
|
||||
}
|
||||
}
|
||||
class ClosureNode(val f: (Player) -> Int): core.game.dialogue.DialogueNode {
|
||||
override fun handle(df: core.game.dialogue.DialogueFile, componentID: Int, buttonID: Int, stage: Int): Int {
|
||||
return f(df.player!!)
|
||||
}
|
||||
}
|
||||
|
||||
class OptionEntry(val text: String, val nextStage: Int, val predicate: (Player) -> Boolean = { _ -> true }) {}
|
||||
|
||||
class OptionsNode(var options: ArrayList<core.game.dialogue.OptionEntry>): core.game.dialogue.DialogueNode {
|
||||
fun optionNames(player: Player): Array<String?> {
|
||||
return options.asSequence().filter({ it.predicate(player) }).map({ it.text }).toList().toTypedArray()
|
||||
}
|
||||
override fun handle(df: core.game.dialogue.DialogueFile, componentID: Int, buttonID: Int, stage: Int): Int {
|
||||
val tmp: Array<String?> = optionNames(df.player!!)
|
||||
if(tmp.size > 1) {
|
||||
df.options(*tmp)
|
||||
return stage + 1
|
||||
} else if(tmp.size == 1) {
|
||||
val tmp: List<core.game.dialogue.OptionEntry> = options.asSequence().filter({ it.predicate(df.player!!) }).toList()
|
||||
df.stage = tmp[0].nextStage
|
||||
df.handle(componentID, 0)
|
||||
return df.stage
|
||||
} else {
|
||||
return END_DIALOGUE
|
||||
}
|
||||
}
|
||||
}
|
||||
class OptionsDispatchNode(var options: ArrayList<core.game.dialogue.OptionEntry>): core.game.dialogue.DialogueNode {
|
||||
override fun handle(df: core.game.dialogue.DialogueFile, componentID: Int, buttonID: Int, stage: Int): Int {
|
||||
val tmp: List<core.game.dialogue.OptionEntry> = options.asSequence().filter({ it.predicate(df.player!!) }).toList()
|
||||
df.stage = tmp[buttonID-1].nextStage
|
||||
df.handle(componentID, 0)
|
||||
return df.stage
|
||||
}
|
||||
}
|
||||
|
||||
class DialogueClause(val predicate: (player: Player) -> Boolean, val nodes: ArrayList<core.game.dialogue.DialogueNode>) {
|
||||
fun handle(df: core.game.dialogue.DialogueFile, componentID: Int, buttonID: Int, stage: Int): Int {
|
||||
if(stage < nodes.size) {
|
||||
return nodes[stage].handle(df, componentID, buttonID, stage)
|
||||
} else {
|
||||
return END_DIALOGUE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class DialogueOptionsBuilder(var target: core.game.dialogue.DialogueBuilderFile, val clauseIndex: Int, var options: ArrayList<core.game.dialogue.OptionEntry>) {
|
||||
fun option(value: String): core.game.dialogue.DialogueBuilder {
|
||||
options.add(core.game.dialogue.OptionEntry(value, target.data[clauseIndex].nodes.size))
|
||||
return core.game.dialogue.DialogueBuilder(target, clauseIndex)
|
||||
}
|
||||
|
||||
fun optionIf(value: String, predicate: (Player) -> Boolean): core.game.dialogue.DialogueBuilder {
|
||||
options.add(core.game.dialogue.OptionEntry(value, target.data[clauseIndex].nodes.size, predicate))
|
||||
return core.game.dialogue.DialogueBuilder(target, clauseIndex)
|
||||
}
|
||||
}
|
||||
|
||||
class DialogueBuilder(var target: core.game.dialogue.DialogueBuilderFile, var clauseIndex: Int = -1) {
|
||||
fun onPredicate(predicate: (player: Player) -> Boolean): core.game.dialogue.DialogueBuilder {
|
||||
target.data.add(core.game.dialogue.DialogueClause(predicate, ArrayList()))
|
||||
clauseIndex = target.data.size - 1
|
||||
return this
|
||||
}
|
||||
fun onQuestStages(name: String, vararg stages: Int): core.game.dialogue.DialogueBuilder {
|
||||
return onPredicate() { player ->
|
||||
val questStage = player.questRepository.getStage(name)
|
||||
return@onPredicate stages.contains(questStage)
|
||||
}
|
||||
}
|
||||
fun playerl(value: String): core.game.dialogue.DialogueBuilder {
|
||||
target.data[clauseIndex].nodes.add(core.game.dialogue.PlayerLNode(value))
|
||||
return this
|
||||
}
|
||||
fun npcl(value: String): core.game.dialogue.DialogueBuilder {
|
||||
target.data[clauseIndex].nodes.add(core.game.dialogue.NpcLNode(value))
|
||||
return this
|
||||
}
|
||||
fun npc(vararg values: String): core.game.dialogue.DialogueBuilder {
|
||||
target.data[clauseIndex].nodes.add(core.game.dialogue.NpcNode(values as Array<String>))
|
||||
return this
|
||||
}
|
||||
fun endWith(f: (Player) -> Unit) {
|
||||
target.data[clauseIndex].nodes.add(core.game.dialogue.ClosureNode({ player ->
|
||||
f(player)
|
||||
return@ClosureNode END_DIALOGUE
|
||||
}))
|
||||
}
|
||||
fun end() {
|
||||
target.data[clauseIndex].nodes.add(core.game.dialogue.ClosureNode({ _ ->
|
||||
return@ClosureNode END_DIALOGUE
|
||||
}))
|
||||
}
|
||||
fun options(): core.game.dialogue.DialogueOptionsBuilder {
|
||||
var options: ArrayList<core.game.dialogue.OptionEntry> = ArrayList()
|
||||
val node = core.game.dialogue.OptionsNode(options)
|
||||
val dispatchNode = core.game.dialogue.OptionsDispatchNode(options)
|
||||
target.data[clauseIndex].nodes.add(node)
|
||||
target.data[clauseIndex].nodes.add(dispatchNode)
|
||||
return core.game.dialogue.DialogueOptionsBuilder(target, clauseIndex, options)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
package core.game.dialogue
|
||||
|
||||
import core.api.splitLines
|
||||
import core.game.component.Component
|
||||
import core.game.node.entity.Entity
|
||||
import core.game.node.entity.npc.NPC
|
||||
import core.game.node.entity.player.Player
|
||||
import core.tools.START_DIALOGUE
|
||||
|
||||
abstract class DialogueFile {
|
||||
var player: Player? = null
|
||||
var npc: NPC? = null
|
||||
var interpreter: core.game.dialogue.DialogueInterpreter? = null
|
||||
open var stage = START_DIALOGUE
|
||||
var dialoguePlugin: core.game.dialogue.DialoguePlugin? = null
|
||||
|
||||
abstract fun handle(componentID: Int, buttonID: Int)
|
||||
|
||||
fun load(player: Player, npc: NPC?, interpreter: core.game.dialogue.DialogueInterpreter): DialogueFile {
|
||||
this.player = player
|
||||
this.npc = npc
|
||||
this.interpreter = interpreter
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
open fun npc(vararg messages: String?): Component? {
|
||||
if (npc != null) {
|
||||
return interpreter!!.sendDialogues(
|
||||
npc,
|
||||
if (npc!!.id > 8591) core.game.dialogue.FacialExpression.OLD_NORMAL else core.game.dialogue.FacialExpression.FRIENDLY,
|
||||
*messages
|
||||
)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
open fun npc(id: Int, vararg messages: String?): Component? {
|
||||
return interpreter!!.sendDialogues(id, core.game.dialogue.FacialExpression.FRIENDLY, *messages)
|
||||
}
|
||||
|
||||
open fun npc(expression: core.game.dialogue.FacialExpression?, vararg messages: String?): Component? {
|
||||
return if (npc == null) {
|
||||
interpreter!!.sendDialogues(0, expression, *messages)
|
||||
} else interpreter!!.sendDialogues(npc, expression, *messages)
|
||||
}
|
||||
|
||||
open fun player(vararg messages: String?): Component? {
|
||||
return interpreter!!.sendDialogues(player, null, *messages)
|
||||
}
|
||||
|
||||
open fun player(expression: core.game.dialogue.FacialExpression?, vararg messages: String?): Component? {
|
||||
return interpreter!!.sendDialogues(player, expression, *messages)
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the automatic linesplitting feature in DialUtils to produce npc dialogues
|
||||
* @param expr the FacialExpression to use, located in the FacialExpression enum.
|
||||
* @param msg the message for the NPC to say
|
||||
*/
|
||||
open fun npcl(expr: core.game.dialogue.FacialExpression?, msg: String?): Component? {
|
||||
return npc(expr, *splitLines(msg!!))
|
||||
}
|
||||
|
||||
open fun npcl(msg: String?): Component? {
|
||||
return npc(*splitLines(msg!!))
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the automatic linesplitting feature in DialUtils to produce player dialogues
|
||||
* @param expr the FacialExpression to use, located in the FacialExpression enum.
|
||||
* @param msg the message for the player to say
|
||||
*/
|
||||
open fun playerl(expr: core.game.dialogue.FacialExpression?, msg: String?): Component? {
|
||||
return player(expr, *splitLines(msg!!))
|
||||
}
|
||||
|
||||
open fun playerl(msg: String?): Component? {
|
||||
return player(*splitLines(msg!!))
|
||||
}
|
||||
|
||||
open fun end(){
|
||||
if(interpreter != null) interpreter!!.close()
|
||||
}
|
||||
|
||||
open fun sendNormalDialogue(entity: Entity?, expression: core.game.dialogue.FacialExpression?, vararg messages: String?) {
|
||||
interpreter!!.sendDialogues(entity, expression, *messages)
|
||||
}
|
||||
|
||||
open fun options(vararg options: String?) {
|
||||
interpreter!!.sendOptions("Select an Option", *options)
|
||||
}
|
||||
|
||||
/**
|
||||
* Use in place of setting the stage to END_DIALOGUE when you want to return to the default dialogue plugin at START_DIALOGUE
|
||||
*/
|
||||
fun endFile(){
|
||||
interpreter!!.dialogue.file = null
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Return to the default dialogue plugin at the given stage.
|
||||
* Should be used in place of setting a new stage. I.E. instead of "stage = END_DIALOGUE" use "returnAtStage(whatever stage)"
|
||||
* @param stage The stage to return to.
|
||||
*/
|
||||
fun returnAtStage(toStage: Int){
|
||||
dialoguePlugin!!.file = null
|
||||
dialoguePlugin!!.stage = toStage
|
||||
}
|
||||
|
||||
/**
|
||||
* Use when you've entered a DialogueFile but current state does not match any possible conditionals.
|
||||
* Sort-of a fail-safe in a sense.
|
||||
*/
|
||||
fun abandonFile(){
|
||||
interpreter!!.dialogue.file = null
|
||||
player("Huh. Nevermind.")
|
||||
}
|
||||
|
||||
open fun getCurrentStage(): Int{
|
||||
return stage
|
||||
}
|
||||
|
||||
fun Int.substage(stage: Int): Int{
|
||||
return this + stage
|
||||
}
|
||||
|
||||
fun dialogue(vararg messages: String){
|
||||
player?.dialogueInterpreter?.sendDialogue(*messages)
|
||||
}
|
||||
|
||||
fun showTopics(vararg topics: Topic<*>) {
|
||||
val validTopics = ArrayList<String>()
|
||||
topics.filter { if(it is IfTopic) it.showCondition else true }.forEach {
|
||||
topic -> interpreter!!.activeTopics.add(topic)
|
||||
validTopics.add(topic.text)
|
||||
}
|
||||
if (validTopics.size == 1) {
|
||||
val topic = topics[0]
|
||||
if(topic.toStage is DialogueFile) {
|
||||
val topicFile = topic.toStage as DialogueFile
|
||||
interpreter!!.dialogue.loadFile(topicFile)
|
||||
} else if(topic.toStage is Int) {
|
||||
stage = topic.toStage as Int
|
||||
}
|
||||
player(topic.text)
|
||||
interpreter!!.activeTopics.clear()
|
||||
}
|
||||
else options(*validTopics.toTypedArray())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,575 @@
|
||||
package core.game.dialogue;
|
||||
|
||||
import core.game.event.DialogueCloseEvent;
|
||||
import core.game.event.DialogueOpenEvent;
|
||||
import core.game.event.DialogueOptionSelectionEvent;
|
||||
import core.cache.def.impl.ItemDefinition;
|
||||
import core.cache.def.impl.NPCDefinition;
|
||||
import core.game.component.Component;
|
||||
import core.game.node.entity.Entity;
|
||||
import core.game.node.entity.npc.NPC;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.game.node.item.Item;
|
||||
import core.net.packet.PacketRepository;
|
||||
import core.net.packet.context.ContainerContext;
|
||||
import core.net.packet.out.ContainerPacket;
|
||||
import core.plugin.PluginManifest;
|
||||
import core.plugin.PluginType;
|
||||
import core.game.system.config.ItemConfigParser;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static core.tools.DialogueConstKt.END_DIALOGUE;
|
||||
|
||||
|
||||
/**
|
||||
* Handles the dialogues.
|
||||
* @author Emperor
|
||||
*/
|
||||
@PluginManifest(type = PluginType.DIALOGUE)
|
||||
public final class DialogueInterpreter {
|
||||
public ArrayList<Topic<?>> activeTopics = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* The dialogue plugins.
|
||||
*/
|
||||
private static final Map<Integer, DialoguePlugin> PLUGINS = new HashMap<>();
|
||||
|
||||
/**
|
||||
* a List of dialogue actions.
|
||||
*/
|
||||
private final List<DialogueAction> actions = new ArrayList<>(10);
|
||||
|
||||
/**
|
||||
* The currently opened dialogue.
|
||||
*/
|
||||
private DialoguePlugin dialogue;
|
||||
|
||||
/**
|
||||
* The current dialogue key.
|
||||
*/
|
||||
private int key;
|
||||
|
||||
/**
|
||||
* The player.
|
||||
*/
|
||||
private final Player player;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code DialogueInterpreter} {@code Object}.
|
||||
* @param player The player.
|
||||
*/
|
||||
public DialogueInterpreter(Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param dialogue the dialogue to set.
|
||||
*/
|
||||
public void setDialogue(DialoguePlugin dialogue) {
|
||||
this.dialogue = dialogue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the dialogue for the given dialogue type.
|
||||
* @param dialogueType The dialogue type.
|
||||
* @param args the args.
|
||||
* @return {@code True} if successful.
|
||||
*/
|
||||
public boolean open(String dialogueType, Object... args) {
|
||||
return open(getDialogueKey(dialogueType), args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the dialogue for the given NPC id.
|
||||
* @param dialogueKey The dialogue key (usually NPC id).
|
||||
* @param args The arguments.
|
||||
* @return {@code True} if successful.
|
||||
*/
|
||||
public boolean open(int dialogueKey, Object... args) {
|
||||
key = dialogueKey;
|
||||
if (args.length > 0 && args[0] instanceof NPC) {
|
||||
NPC npc = (NPC) args[0];
|
||||
npc.setDialoguePlayer(player);
|
||||
try { //this prevents the dialogue interpreter from dying when you try opening an NPC's dialogue without passing the NPC itself as an argument
|
||||
npc.getWalkingQueue().reset();
|
||||
npc.getPulseManager().clear();
|
||||
} catch(Exception e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else if (args.length < 1) {
|
||||
args = new Object[] { dialogueKey };
|
||||
}
|
||||
DialoguePlugin plugin = PLUGINS.get(dialogueKey);
|
||||
if (plugin == null) {
|
||||
return false;
|
||||
}
|
||||
if (player.isDebug()) {
|
||||
player.sendMessage("Dialogue opening - " + plugin.getClass().getSimpleName() + ", key=" + dialogueKey + "");
|
||||
}
|
||||
this.dialogue = plugin.newInstance(player);
|
||||
if (dialogue == null || !dialogue.open(args)) {
|
||||
dialogue = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dialogue != null) {
|
||||
player.dispatch(new DialogueOpenEvent(dialogue));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void open(DialogueFile file, Object... args){
|
||||
this.dialogue = new EmptyPlugin(player,file);
|
||||
this.dialogue.open(args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles an dialogue input.
|
||||
* @param componentId The id of the chatbox component.
|
||||
* @param buttonId The button id.
|
||||
*/
|
||||
public void handle(int componentId, int buttonId) {
|
||||
player.setAttribute("chatbox-buttonid",buttonId);
|
||||
if((player.getDialogueInterpreter().getDialogue().file != null && player.getDialogueInterpreter().getDialogue().file.getCurrentStage() == END_DIALOGUE) || player.getDialogueInterpreter().getDialogue().stage == END_DIALOGUE){
|
||||
player.getInterfaceManager().closeChatbox();
|
||||
player.getInterfaceManager().openChatbox(137);
|
||||
player.getDialogueInterpreter().dialogue.finished = true;
|
||||
close();
|
||||
return;
|
||||
}
|
||||
DialogueFile file = dialogue.file;
|
||||
if (!activeTopics.isEmpty()) {
|
||||
Topic<?> topic = activeTopics.get(buttonId - 2);
|
||||
|
||||
if (!topic.getSkipPlayer())
|
||||
sendDialogues(player, topic.getExpr(), topic.getText());
|
||||
|
||||
if(topic.getToStage() instanceof DialogueFile) {
|
||||
DialogueFile topicFile = (DialogueFile) topic.getToStage();
|
||||
dialogue.loadFile(topicFile);
|
||||
} else if(topic.getToStage() instanceof Integer) {
|
||||
int stage = (Integer) topic.getToStage();
|
||||
if (file == null) dialogue.stage = stage;
|
||||
else file.setStage(stage);
|
||||
}
|
||||
activeTopics.clear();
|
||||
|
||||
if (topic.getSkipPlayer())
|
||||
handle(componentId, buttonId);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(file != null){
|
||||
player.dispatch(
|
||||
new DialogueOptionSelectionEvent(
|
||||
file,
|
||||
file.getStage(),
|
||||
buttonId - 1
|
||||
)
|
||||
);
|
||||
|
||||
file.handle(componentId,buttonId - 1);
|
||||
} else {
|
||||
player.dispatch(
|
||||
new DialogueOptionSelectionEvent(
|
||||
dialogue,
|
||||
dialogue.stage,
|
||||
buttonId - 1
|
||||
)
|
||||
);
|
||||
|
||||
dialogue.handle(componentId, buttonId - 1);//here
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the current dialogue.
|
||||
* @return {@code True} if successful.
|
||||
*/
|
||||
public boolean close() {
|
||||
if (dialogue != null) {
|
||||
actions.clear();
|
||||
|
||||
if (player.getInterfaceManager().getChatbox() != null && player.getInterfaceManager().getChatbox().getCloseEvent() != null) {
|
||||
return true;
|
||||
}
|
||||
if (dialogue != null) {
|
||||
DialoguePlugin d = dialogue;
|
||||
dialogue = null;
|
||||
d.close();
|
||||
player.dispatch(new DialogueCloseEvent(d));
|
||||
}
|
||||
}
|
||||
activeTopics.clear();
|
||||
return dialogue == null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts a dialogue plugin on the mapping.
|
||||
* @param id The NPC id (or {@code 1 << 16 | dialogueId} when the dialogue
|
||||
* isn't for an NPC).
|
||||
* @param plugin The plugin.
|
||||
*/
|
||||
public static void add(int id, DialoguePlugin plugin) {
|
||||
if (PLUGINS.containsKey(id)) {
|
||||
throw new IllegalArgumentException("Dialogue " + (id & 0xFFFF) + " is already in use - [old=" + PLUGINS.get(id).getClass().getSimpleName() + ", new=" + plugin.getClass().getSimpleName() + "]!");
|
||||
}
|
||||
PLUGINS.put(id, plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send plain messages based on the amount of specified messages.
|
||||
* @param messages The messages.
|
||||
* @return The chatbox component.
|
||||
*/
|
||||
public Component sendDialogue(String... messages) {
|
||||
if (messages.length < 1 || messages.length > 4) {
|
||||
return null;
|
||||
}
|
||||
int interfaceId = 209 + messages.length;
|
||||
for (int i = 0; i < messages.length; i++) {
|
||||
player.getPacketDispatch().sendString(messages[i], interfaceId, i + 1);
|
||||
}
|
||||
player.getInterfaceManager().openChatbox(interfaceId);
|
||||
player.getPacketDispatch().sendInterfaceConfig(player.getInterfaceManager().getChatbox().getId(), 1, false);
|
||||
return player.getInterfaceManager().getChatbox();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a plane message and hides the continue button.
|
||||
* @param hideContinue if we should hide it or not.
|
||||
* @param messages the messages.
|
||||
* @return the component.
|
||||
*/
|
||||
public Component sendPlainMessage(final boolean hideContinue, String... messages) {
|
||||
sendDialogue(messages);
|
||||
player.getPacketDispatch().sendInterfaceConfig(player.getInterfaceManager().getChatbox().getId(), (messages.length + 1), hideContinue);
|
||||
return player.getInterfaceManager().getChatbox();
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the destroy item chatbox interface.
|
||||
* @param id The item id.
|
||||
* @param message The message to display.
|
||||
* @return The component.
|
||||
*/
|
||||
public Component sendDestroyItem(int id, String message) {
|
||||
player.getInterfaceManager().openChatbox(94);
|
||||
PacketRepository.send(ContainerPacket.class, new ContainerContext(player, 94, 93, 93, new Item[] { new Item(id) }, 1, false));
|
||||
String text = ItemDefinition.forId(id).getConfiguration(ItemConfigParser.DESTROY_MESSAGE, "Are you sure you want to destroy this object?");
|
||||
if (text.length() > 200) {
|
||||
String[] words = text.split(" ");
|
||||
StringBuilder sb = new StringBuilder(words[0]);
|
||||
for (int i = 1; i < words.length; i++) {
|
||||
if (i == (words.length / 2)) {
|
||||
sb.append("<br>");
|
||||
} else {
|
||||
sb.append(" ");
|
||||
}
|
||||
sb.append(words[i]);
|
||||
}
|
||||
text = sb.toString();
|
||||
}
|
||||
player.getPacketDispatch().sendString("Are you sure you want to destroy this object?", 94, 2);
|
||||
player.getPacketDispatch().sendString("Yes.", 94, 3);
|
||||
player.getPacketDispatch().sendString("No.", 94, 4);
|
||||
player.getPacketDispatch().sendString(text, 94, 7);
|
||||
player.getPacketDispatch().sendString(ItemDefinition.forId(id).getName(), 94, 8);
|
||||
return player.getInterfaceManager().getChatbox();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send plane messages with a blue title.
|
||||
* @param title The title.
|
||||
* @param messages The messages.
|
||||
* @return The chatbox component.
|
||||
*/
|
||||
public Component sendPlaneMessageWithBlueTitle(String title, String... messages) {
|
||||
player.getPacketDispatch().sendString(title, 372, 0);
|
||||
for (int i = 0; i < messages.length; i++) {
|
||||
player.getPacketDispatch().sendString(messages[i], 372, i + 1);
|
||||
}
|
||||
player.getInterfaceManager().openChatbox(372);
|
||||
return player.getInterfaceManager().getChatbox();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send plane messages with scroll and a blue title.
|
||||
* @param title The title.
|
||||
* @param messages The messages.
|
||||
* @return The chatbox component.
|
||||
*/
|
||||
public Component sendScrollMessageWithBlueTitle(String title, String... messages) {
|
||||
for (int i = 0; i < 11; i++) {
|
||||
player.getPacketDispatch().sendString(" ", 421, i + 2);
|
||||
}
|
||||
player.getPacketDispatch().sendString(title, 421, 1);
|
||||
for (int i = 0; i < messages.length; i++) {
|
||||
player.getPacketDispatch().sendString(messages[i], 421, i + 2);
|
||||
}
|
||||
player.getInterfaceManager().openChatbox(421);
|
||||
return player.getInterfaceManager().getChatbox();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message with an item next to it.
|
||||
* @param itemId The item id.
|
||||
*/
|
||||
public Component sendItemMessage(int itemId, String... messages) {
|
||||
player.getInterfaceManager().openChatbox(131);
|
||||
String message = messages[0];
|
||||
for (int i = 1; i < messages.length; i++) {
|
||||
message += "<br>" + messages[i];
|
||||
}
|
||||
player.getPacketDispatch().sendString(message, 131, 1);
|
||||
player.getPacketDispatch().sendItemOnInterface(itemId, 1, 131, 2);
|
||||
return player.getInterfaceManager().getChatbox();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message with an item next to it.
|
||||
*/
|
||||
public Component sendItemMessage(final Item item, String... messages) {
|
||||
player.getInterfaceManager().openChatbox(131);
|
||||
String message = messages[0];
|
||||
for (int i = 1; i < messages.length; i++) {
|
||||
message += "<br>" + messages[i];
|
||||
}
|
||||
player.getPacketDispatch().sendString(message, 131, 1);
|
||||
player.getPacketDispatch().sendItemOnInterface(item.getId(), item.getAmount(), 131, 2);
|
||||
return player.getInterfaceManager().getChatbox();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message with an item next to it.
|
||||
* @param message The message.
|
||||
*/
|
||||
public Component sendDoubleItemMessage(int first, int second, String message) {
|
||||
player.getInterfaceManager().openChatbox(131);
|
||||
player.getPacketDispatch().sendString(message, 131, 1);
|
||||
player.getPacketDispatch().sendItemOnInterface(first, 1, 131, 0);
|
||||
player.getPacketDispatch().sendItemOnInterface(second, 1, 131, 2);
|
||||
return player.getInterfaceManager().getChatbox();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message with an item next to it.
|
||||
* @param message The message.
|
||||
*/
|
||||
public Component sendDoubleItemMessage(Item first, Item second, String message) {
|
||||
player.getInterfaceManager().openChatbox(131);
|
||||
player.getPacketDispatch().sendString(message, 131, 1);
|
||||
player.getPacketDispatch().sendItemOnInterface(first.getId(), first.getAmount(), 131, 0);
|
||||
player.getPacketDispatch().sendItemOnInterface(second.getId(), second.getAmount(), 131, 2);
|
||||
return player.getInterfaceManager().getChatbox();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send dialogues based on the amount of specified messages.
|
||||
* @param entity The entity.
|
||||
* @param expression The entity's facial expression.
|
||||
* @param messages The messages.
|
||||
* @return The chatbox component.
|
||||
*/
|
||||
public Component sendDialogues(Entity entity, FacialExpression expression, String... messages) {
|
||||
return sendDialogues(entity, expression == null ? -1 : expression.getAnimationId(), messages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send dialogues based on the amount of specified messages.
|
||||
* @param entity The entity.
|
||||
* @param expression The entity's facial expression.
|
||||
* @param messages The messages.
|
||||
* @return The chatbox component.
|
||||
*/
|
||||
public Component sendDialogues(Entity entity, int expression, String... messages) {
|
||||
return sendDialogues(entity instanceof Player ? -1 : ((NPC) entity).getShownNPC(player).getId(), expression, messages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send dialogues based on the amount of specified messages.
|
||||
* @param npcId The npc id.
|
||||
* @param expression The entity's facial expression.
|
||||
* @param messages The messages.
|
||||
* @param hide the continue.
|
||||
* @return The chatbox component.
|
||||
*/
|
||||
public Component sendDialogues(int npcId, FacialExpression expression, boolean hide, String... messages) {
|
||||
sendDialogues(npcId, expression == null ? -1 : expression.getAnimationId(), messages);
|
||||
return player.getInterfaceManager().getChatbox();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send dialogues based on the amount of specified messages.
|
||||
* @param expression The entity's facial expression.
|
||||
* @param messages The messages.
|
||||
* @param hide the continue.
|
||||
* @return The chatbox component.
|
||||
*/
|
||||
public Component sendDialogues(Entity entity, FacialExpression expression, boolean hide, String... messages) {
|
||||
sendDialogues(entity, expression, messages);
|
||||
player.getPacketDispatch().sendInterfaceConfig(player.getInterfaceManager().getChatbox().getId(), 3, hide);
|
||||
return player.getInterfaceManager().getChatbox();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send dialogues based on the amount of specified messages.
|
||||
* @param expression The entity's facial expression.
|
||||
* @param messages The messages.
|
||||
* @param hide the continue.
|
||||
* @return The chatbox component.
|
||||
*/
|
||||
public Component sendDialogues(Entity entity, int expression, boolean hide, String... messages) {
|
||||
sendDialogues(entity, expression, messages);
|
||||
player.getPacketDispatch().sendInterfaceConfig(player.getInterfaceManager().getChatbox().getId(), 3, hide);
|
||||
return player.getInterfaceManager().getChatbox();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send dialogues based on the amount of specified messages.
|
||||
* @param expression The entity's facial expression.
|
||||
* @param messages The messages.
|
||||
* @return The chatbox component.
|
||||
*/
|
||||
public Component sendDialogues(int npcId, int expression, boolean hide, String... messages) {
|
||||
sendDialogues(npcId, expression, messages);
|
||||
player.getPacketDispatch().sendInterfaceConfig(player.getInterfaceManager().getChatbox().getId(), 3, hide);
|
||||
return player.getInterfaceManager().getChatbox();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send dialogues based on the amount of specified messages.
|
||||
* @param npcId The npc id.
|
||||
* @param expression The entity's facial expression.
|
||||
* @param messages The messages.
|
||||
* @return The chatbox component.
|
||||
*/
|
||||
public Component sendDialogues(int npcId, FacialExpression expression, String... messages) {
|
||||
return sendDialogues(npcId, expression == null ? -1 : expression.getAnimationId(), messages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send dialogues based on the amount of specified messages.
|
||||
* @param npcId The npc id.
|
||||
* @param expression The entity's facial expression.
|
||||
* @param messages The messages.
|
||||
* @return The chatbox component.
|
||||
*/
|
||||
public Component sendDialogues(int npcId, int expression, String... messages) {
|
||||
if (messages.length < 1 || messages.length > 4) {
|
||||
return null;
|
||||
}
|
||||
boolean npc = npcId > -1;
|
||||
int interfaceId = (npc ? 240 : 63) + messages.length;
|
||||
if (expression == -1) {
|
||||
expression = FacialExpression.HALF_GUILTY.getAnimationId();
|
||||
}
|
||||
player.getPacketDispatch().sendAnimationInterface(expression, interfaceId, 2);
|
||||
if (npc) {
|
||||
player.getPacketDispatch().sendNpcOnInterface(npcId, interfaceId, 2);
|
||||
player.getPacketDispatch().sendString(NPCDefinition.forId(npcId).getName(), interfaceId, 3);
|
||||
} else {
|
||||
player.getPacketDispatch().sendPlayerOnInterface(interfaceId, 2);
|
||||
player.getPacketDispatch().sendString(player.getUsername(), interfaceId, 3);
|
||||
}
|
||||
for (int i = 0; i < messages.length; i++) {
|
||||
player.getPacketDispatch().sendString(messages[i].toString().replace("@name", player.getUsername()), interfaceId, (i + 4));
|
||||
}
|
||||
player.getInterfaceManager().openChatbox(interfaceId);
|
||||
player.getPacketDispatch().sendInterfaceConfig(player.getInterfaceManager().getChatbox().getId(), 3, false);
|
||||
return player.getInterfaceManager().getChatbox();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send options based on the amount of specified options.
|
||||
* @param title The title.
|
||||
* @param options The options.
|
||||
*/
|
||||
public Component sendOptions(Object title, String... options) {
|
||||
int interfaceId = 224 + (2 * options.length);
|
||||
if (options.length < 2 || options.length > 5) {
|
||||
return null;
|
||||
}
|
||||
if (title != null) {
|
||||
player.getPacketDispatch().sendString(title.toString(), interfaceId, 1);
|
||||
}
|
||||
for (int i = 0; i < options.length; i++) {
|
||||
player.getPacketDispatch().sendString(options[i].toString(), interfaceId, i + 2);
|
||||
}
|
||||
player.getInterfaceManager().openChatbox(interfaceId);
|
||||
return player.getInterfaceManager().getChatbox();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a input run script.
|
||||
* @param string The strings.
|
||||
* @param objects The arguments.
|
||||
*/
|
||||
public void sendInput(boolean string, Object... objects) {
|
||||
player.getPacketDispatch().sendRunScript(string ? 109 : 108, "s", objects);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a long input.
|
||||
* @param objects the objects.
|
||||
*/
|
||||
public void sendLongInput(Object... objects) {
|
||||
player.getPacketDispatch().sendRunScript(110, "s", objects);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the private message input.
|
||||
* @param reciever The receiver.
|
||||
*/
|
||||
public void sendMessageInput(String reciever) {
|
||||
player.getPacketDispatch().sendRunScript(107, "s", reciever);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the dialogue for the given id is added.
|
||||
* @param id The NPC id/dialogue id.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public static boolean contains(int id) {
|
||||
return PLUGINS.containsKey(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the currently opened dialogue.
|
||||
* @return The dialogue plugin.
|
||||
*/
|
||||
public DialoguePlugin getDialogue() {
|
||||
return dialogue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reserves a key for the name.
|
||||
* @param name The name.
|
||||
* @return The key.
|
||||
*/
|
||||
public static int getDialogueKey(String name) {
|
||||
return 1 << 16 | name.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a dialogue reward.
|
||||
* @param action the reward.
|
||||
*/
|
||||
public void addAction(DialogueAction action) {
|
||||
actions.add(action);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the actions.
|
||||
* @return The actions.
|
||||
*/
|
||||
public List<DialogueAction> getActions() {
|
||||
return actions;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,390 @@
|
||||
package core.game.dialogue;
|
||||
|
||||
import core.game.component.Component;
|
||||
import core.game.node.entity.Entity;
|
||||
import core.game.node.entity.npc.NPC;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.plugin.Plugin;
|
||||
import core.plugin.PluginManifest;
|
||||
import core.plugin.PluginType;
|
||||
import core.tools.SystemLogger;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import static core.api.DialUtilsKt.splitLines;
|
||||
import static core.tools.DialogueConstKt.DIALOGUE_INITIAL_OPTIONS_HANDLE;
|
||||
import static core.tools.DialogueConstKt.START_DIALOGUE;
|
||||
|
||||
/**
|
||||
* Represents a dialogue plugin.
|
||||
* @author Emperor
|
||||
*/
|
||||
@PluginManifest(type = PluginType.DIALOGUE)
|
||||
public abstract class DialoguePlugin implements Plugin<Player> {
|
||||
|
||||
/**
|
||||
* Represents the red string.
|
||||
*/
|
||||
protected static final String RED = "<col=8A0808>";
|
||||
|
||||
/**
|
||||
* Represents the blue string.
|
||||
*/
|
||||
protected static final String BLUE = "<col=08088A>";
|
||||
|
||||
/**
|
||||
* The player.
|
||||
*/
|
||||
protected Player player;
|
||||
|
||||
/**
|
||||
* The dialogue interpreter.
|
||||
*/
|
||||
protected DialogueInterpreter interpreter;
|
||||
|
||||
public DialogueFile file;
|
||||
|
||||
protected ArrayList<String> optionNames = new ArrayList<String>(10);
|
||||
protected ArrayList<DialogueFile> optionFiles = new ArrayList<DialogueFile>(10);
|
||||
|
||||
/**
|
||||
* Two options interface.
|
||||
*/
|
||||
protected final int TWO_OPTIONS = 228;
|
||||
|
||||
/**
|
||||
* Three options interface.
|
||||
*/
|
||||
protected final int THREE_OPTIONS = 230;
|
||||
|
||||
/**
|
||||
* Four options interface.
|
||||
*/
|
||||
protected final int FOUR_OPTIONS = 232;
|
||||
|
||||
/**
|
||||
* Five options interface.
|
||||
*/
|
||||
protected final int FIVE_OPTIONS = 234;
|
||||
|
||||
/**
|
||||
* The NPC the player is talking with.
|
||||
*/
|
||||
protected NPC npc;
|
||||
|
||||
/**
|
||||
* The current dialogue stage.
|
||||
*/
|
||||
public int stage;
|
||||
|
||||
/**
|
||||
* If the dialogue is finished.
|
||||
*/
|
||||
protected boolean finished;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code DialoguePlugin} {@code Object}.
|
||||
*/
|
||||
public DialoguePlugin() {
|
||||
/*
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
|
||||
public String pirateGender() {
|
||||
return (player.isMale() ? "lad" : "lass");
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code DialoguePlugin} {@code Object}.
|
||||
* @param player The player.
|
||||
*/
|
||||
public DialoguePlugin(Player player) {
|
||||
this.player = player;
|
||||
if (player != null) {
|
||||
this.interpreter = player.getDialogueInterpreter();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes this plugin.
|
||||
*/
|
||||
public void init() {
|
||||
for (int id : getIds()) {
|
||||
DialogueInterpreter.add(id, this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes <b>(but does not end)</b> the dialogue.
|
||||
* @return {@code True} if the dialogue succesfully closed.
|
||||
*/
|
||||
public boolean close() {
|
||||
player.getInterfaceManager().closeChatbox();
|
||||
player.getInterfaceManager().openChatbox(137);
|
||||
if(file != null) file.end();
|
||||
finished = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void sendNormalDialogue(Entity entity, FacialExpression expression, String... messages) {
|
||||
interpreter.sendDialogues(entity, expression, messages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments the stage variable.
|
||||
*/
|
||||
public void increment() {
|
||||
stage++;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Increments the stage variable.
|
||||
* @return The stage variable.
|
||||
*/
|
||||
public int getAndIncrement() {
|
||||
return stage++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends the dialogue.
|
||||
*/
|
||||
public void end() {
|
||||
if (interpreter != null) {
|
||||
interpreter.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void finish() {
|
||||
setStage(-1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object fireEvent(String identifier, Object... args) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DialoguePlugin newInstance(Player player) {
|
||||
try {
|
||||
Class<?> classReference = Class.forName(this.getClass().getCanonicalName());
|
||||
|
||||
return (DialoguePlugin)classReference
|
||||
.getDeclaredConstructor(Player.class)
|
||||
.newInstance(player);
|
||||
} catch (ClassNotFoundException
|
||||
| IllegalAccessException
|
||||
| IllegalArgumentException
|
||||
| NoSuchMethodException
|
||||
| InvocationTargetException
|
||||
| InstantiationException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the dialogue.
|
||||
* @param args The arguments.
|
||||
* @return {@code True} if the dialogue plugin succesfully opened.
|
||||
*/
|
||||
public boolean open(Object... args) {
|
||||
if (args.length > 0 && args[0] instanceof NPC) {
|
||||
npc = (NPC)args[0];
|
||||
}
|
||||
|
||||
if (npc == null) {
|
||||
SystemLogger.logWarn(this.getClass(),
|
||||
args[0].getClass().getSimpleName() +
|
||||
"Is not assigning an NPC. Whoever did that should fix it."
|
||||
);
|
||||
}
|
||||
|
||||
player.getDialogueInterpreter().handle(0, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the progress of this dialogue..
|
||||
* @return {@code True} if the dialogue has started.
|
||||
*/
|
||||
public abstract boolean handle(int interfaceId, int buttonId);
|
||||
|
||||
/**
|
||||
* Gets the ids of the NPCs using this dialogue plugin.
|
||||
* @return The array of NPC ids.
|
||||
*/
|
||||
public abstract int[] getIds();
|
||||
|
||||
/**
|
||||
* Method wrapper to send an npc dial.
|
||||
* @return the component.
|
||||
*/
|
||||
public Component npc(final String... messages) {
|
||||
if (npc == null) {
|
||||
return interpreter.sendDialogues(getIds()[0], getIds()[0] > 8591 ? FacialExpression.OLD_NORMAL : FacialExpression.FRIENDLY, messages);
|
||||
}
|
||||
return interpreter.sendDialogues(npc, npc.getId() > 8591 ? FacialExpression.OLD_NORMAL : FacialExpression.FRIENDLY, messages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method wrapper to send an npc dial.
|
||||
* @param id the id.
|
||||
* @return the component.
|
||||
*/
|
||||
public Component npc(int id, final String... messages) {
|
||||
return interpreter.sendDialogues(id, FacialExpression.FRIENDLY, messages);
|
||||
}
|
||||
|
||||
public Component sendDialogue(String... messages) {
|
||||
return interpreter.sendDialogue(messages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method wrapper to send an npc dial.
|
||||
* @return the component.
|
||||
*/
|
||||
public Component npc(FacialExpression expression, final String... messages) {
|
||||
if (npc == null) {
|
||||
return interpreter.sendDialogues(getIds()[0], expression, messages);
|
||||
}
|
||||
return interpreter.sendDialogues(npc, expression, messages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method wrapper to send a player dial.
|
||||
* @return the component.
|
||||
*/
|
||||
public Component player(final String... messages) {
|
||||
return interpreter.sendDialogues(player, null, messages);
|
||||
}
|
||||
/**
|
||||
* Method wrapper to send a player dial.
|
||||
* @return the component.
|
||||
*/
|
||||
public Component player(FacialExpression expression, final String... messages) {
|
||||
return interpreter.sendDialogues(player, expression, messages);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to send options.
|
||||
* @param options the options.
|
||||
*/
|
||||
public void options(final String... options) {
|
||||
interpreter.sendOptions("Select an Option", options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the dialogue plugin is finished.
|
||||
* @return {@code True} if so.
|
||||
*/
|
||||
public boolean isFinished() {
|
||||
return finished;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the player.
|
||||
* @return The player.
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the stage.
|
||||
* @param i the stage.
|
||||
*/
|
||||
public void setStage(int i) {
|
||||
this.stage = i;
|
||||
}
|
||||
|
||||
public void next() {
|
||||
this.stage += 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a DialogueFile and sets its stage to START_DIALOGUE, and diverts all further handling for the conversation to the file.
|
||||
* @param file the DialogueFile to load.
|
||||
*/
|
||||
public void loadFile(DialogueFile file){
|
||||
if(file == null) return;
|
||||
this.file = file.load(player,npc,interpreter);
|
||||
this.file.setDialoguePlugin(this);
|
||||
stage = START_DIALOGUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an option to the list of possible choices a player can pick from. Helps build the options interface for sendChoices()
|
||||
* @param name the name of the quest/activity to talk about. Turns into "Talk about $name" on the option interface.
|
||||
* @param file the DialogueFile that the option loads when selected.
|
||||
*/
|
||||
public void addOption(String name, DialogueFile file){
|
||||
optionNames.add("Talk about " + name);
|
||||
optionFiles.add(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the player a list of conversation options if there's more than one choice. I.E. multiple quest lines.
|
||||
* @return true if an options interface was sent, false if not.
|
||||
*/
|
||||
public boolean sendChoices(){
|
||||
if(optionNames.size() == 1){
|
||||
loadFile(optionFiles.get(0));
|
||||
return false;
|
||||
} else if(optionNames.isEmpty()) {
|
||||
stage = START_DIALOGUE;
|
||||
return false;
|
||||
} else {
|
||||
options(optionNames.toArray(new String[0]));
|
||||
stage = DIALOGUE_INITIAL_OPTIONS_HANDLE;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the automatic linesplitting feature in DialUtils to produce npc dialogues
|
||||
* @param expr the FacialExpression to use, located in the FacialExpression enum.
|
||||
* @param msg the message for the NPC to say
|
||||
*/
|
||||
public Component npcl(FacialExpression expr, String msg){
|
||||
return npc(expr, splitLines(msg, 54));
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the automatic linesplitting feature in DialUtils to produce player dialogues
|
||||
* @param expr the FacialExpression to use, located in the FacialExpression enum.
|
||||
* @param msg the message for the player to say
|
||||
*/
|
||||
public Component playerl(FacialExpression expr, String msg){
|
||||
return player(expr, splitLines(msg, 54));
|
||||
}
|
||||
|
||||
public void showTopics(Topic<?>... topics) {
|
||||
ArrayList<String> validTopics = new ArrayList<>();
|
||||
for(Topic<?> topic : topics)
|
||||
{
|
||||
if(topic instanceof IfTopic && !((IfTopic<?>) topic).getShowCondition()) continue;
|
||||
interpreter.activeTopics.add(topic);
|
||||
validTopics.add(topic.getText());
|
||||
}
|
||||
|
||||
if (validTopics.size() == 1) {
|
||||
Topic topic = interpreter.activeTopics.get(0);
|
||||
|
||||
if(topic.getToStage() instanceof DialogueFile) {
|
||||
DialogueFile topicFile = (DialogueFile) topic.getToStage();
|
||||
interpreter.getDialogue().loadFile(topicFile);
|
||||
} else if(topic.getToStage() instanceof Integer) {
|
||||
stage = (Integer) topic.getToStage();
|
||||
}
|
||||
|
||||
player(topic.getText());
|
||||
interpreter.activeTopics.clear();
|
||||
}
|
||||
|
||||
options(validTopics.toArray(new String[0]));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package core.game.dialogue
|
||||
|
||||
/**
|
||||
* Topic/IfTopic system backported from my personal project
|
||||
* @author Ceikry
|
||||
*/
|
||||
open class Topic<T>(val expr: core.game.dialogue.FacialExpression, val text: String, val toStage: T, val skipPlayer: Boolean = false) {
|
||||
constructor(text: String, toStage: T, skipPlayer: Boolean = false) : this(core.game.dialogue.FacialExpression.ASKING, text, toStage, skipPlayer)
|
||||
}
|
||||
class IfTopic<T>(expr: core.game.dialogue.FacialExpression, text: String, toStage: T, val showCondition: Boolean, skipPlayer: Boolean = false) : Topic<T>(expr, text, toStage, skipPlayer) {
|
||||
constructor(text: String, toStage: T, showCondition: Boolean, skipPlayer: Boolean = false) : this(core.game.dialogue.FacialExpression.ASKING, text, toStage, showCondition, skipPlayer)
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package core.game.dialogue
|
||||
|
||||
import core.game.node.entity.npc.NPC
|
||||
import core.game.node.entity.player.Player
|
||||
import core.tools.START_DIALOGUE
|
||||
|
||||
class EmptyPlugin(player: Player? = null,val file: DialogueFile?) : core.game.dialogue.DialoguePlugin(player) {
|
||||
override fun newInstance(player: Player?): core.game.dialogue.DialoguePlugin {
|
||||
return EmptyPlugin(player,null)
|
||||
}
|
||||
|
||||
override fun open(vararg args: Any?): Boolean {
|
||||
if(args.isNotEmpty() && args[0] is NPC){
|
||||
npc = args[0] as NPC
|
||||
}
|
||||
stage = START_DIALOGUE
|
||||
loadFile(file)
|
||||
interpreter.handle(0,0)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun handle(interfaceId: Int, buttonId: Int): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun getIds(): IntArray {
|
||||
return intArrayOf(Integer.MAX_VALUE)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
package core.game.dialogue;
|
||||
|
||||
/**
|
||||
* Represents the facial expressions (the animations the entity does when
|
||||
* talking).
|
||||
*
|
||||
* @author Emperor
|
||||
* @author Empathy
|
||||
*/
|
||||
public enum FacialExpression {
|
||||
|
||||
/**
|
||||
* The normal talking expression.
|
||||
*/
|
||||
|
||||
//Names based off https://2009scape.wiki/w/Chathead/Animations
|
||||
|
||||
//Chat heads from oldschool 2009scape?
|
||||
//Maybe for gnomes or dwarves? Chat heads are frozen when used on Human NPCs
|
||||
OLD_HAPPY(588),
|
||||
OLD_CALM_TALK1(589),
|
||||
OLD_CALM_TALK2(590),
|
||||
OLD_DEFAULT(591),
|
||||
OLD_EVIL1(592),
|
||||
OLD_EVIL2(593),
|
||||
OLD_NORMAL(594),
|
||||
OLD_SNEAKY(595),
|
||||
OLD_DISTRESSED(596),
|
||||
OLD_DISTRESSED2(597),
|
||||
OLD_ALMOST_CRYING(598),
|
||||
OLD_BOWS_HEAD_SAD(599),
|
||||
OLD_DRUNK_LEFT(600),
|
||||
OLD_DRUNK_RIGHT(601),
|
||||
OLD_NOT_INTERESTED(602),
|
||||
OLD_SLEEPY(603),
|
||||
OLD_PLAIN_EVIL(604),
|
||||
OLD_LAUGH1(605),
|
||||
OLD_LAUGH2(606),
|
||||
OLD_LAUGH3(607),
|
||||
OLD_LAUGH4(608),
|
||||
OLD_EVIL_LAUGH(609),
|
||||
OLD_SAD(610),
|
||||
OLD_MORE_SAD(611),
|
||||
OLD_ON_ONE_HAND(612),
|
||||
OLD_NEARLY_CRYING(613),
|
||||
OLD_ANGRY1(614),
|
||||
OLD_ANGRY2(615),
|
||||
OLD_ANGRY3(616),
|
||||
OLD_ANGRY4(617),
|
||||
|
||||
//Chatheads from 2009?
|
||||
NOD_YES(9741),
|
||||
WORRIED(9743),
|
||||
HALF_WORRIED(9745), //Not on the wiki, first half of worried
|
||||
AMAZED(9746),
|
||||
EXTREMELY_SHOCKED(9750),
|
||||
GUILTY(9758),
|
||||
HALF_GUILTY(9760), //Not on the wiki, first half of guilty
|
||||
SAD(9761),
|
||||
CRYING(9765),
|
||||
HALF_CRYING(9768), //Not on the wiki, but plays the first half of the crying animation
|
||||
AFRAID(9772),
|
||||
SCARED(9776),
|
||||
PANICKED(9780),
|
||||
ANNOYED(9784),
|
||||
ANGRY(9785),
|
||||
FURIOUS(9792),
|
||||
ANGRY_WITH_SMILE(9796), // Not on the wiki
|
||||
ANGRY_WITH_SMILE_AND_EVIL_EYE(9798), //Not on the Wiki
|
||||
SLEEPING(9802),
|
||||
SILENT(9804),
|
||||
NEUTRAL(9808),
|
||||
THINKING(9812),
|
||||
HALF_THINKING(9814),
|
||||
DISGUSTED(9816),
|
||||
DISGUSTED_HEAD_SHAKE(9823), //Not on the wiki
|
||||
ASKING(9827),
|
||||
HALF_ASKING(9830), //Not on wiki, first half of Asking
|
||||
ROLLING_EYES(9831), //9832, 9833 are the same
|
||||
HALF_ROLLING_EYES(9834), //Not on Wiki, first half of Rolling eyes
|
||||
DRUNK(9835),
|
||||
SUSPICIOUS(9836),
|
||||
LAUGH(9840),
|
||||
LOUDLY_LAUGHING(9841),
|
||||
EVIL_LAUGH(9842),
|
||||
FRIENDLY(9844),
|
||||
HAPPY(9847),
|
||||
JOLLY(9851),
|
||||
STRUGGLE(9865), //TODO: More?
|
||||
//9855-9857 are like disgusted? does it just repeat after this?
|
||||
|
||||
//Child Chathead?
|
||||
CHILD_EVIL_LAUGH(7171),
|
||||
CHILD_FRIENDLY(7172),
|
||||
CHILD_NORMAL(7173),
|
||||
CHILD_NEUTRAL(7174),
|
||||
CHILD_LOUDLY_LAUGHING(7175),
|
||||
CHILD_THINKING(7176),
|
||||
CHILD_SAD(7177),
|
||||
CHILD_GUILTY(7178),
|
||||
CHILD_SUSPICIOUS(7179); //TODO: More?
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The animation id.
|
||||
*/
|
||||
private final int animationId;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code FacialExpression} {@code Object}.
|
||||
*
|
||||
* @param animationId The animation id.
|
||||
*/
|
||||
FacialExpression(int animationId) {
|
||||
this.animationId = animationId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the animation id.
|
||||
*
|
||||
* @return The animation id.
|
||||
*/
|
||||
public int getAnimationId() {
|
||||
return animationId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package core.game.dialogue;
|
||||
|
||||
import core.plugin.Initializable;
|
||||
import core.game.node.entity.player.Player;
|
||||
|
||||
/**
|
||||
* Represents a simple dialogue.
|
||||
* @author 'Vexia
|
||||
*/
|
||||
@Initializable
|
||||
public class SimpleDialoguePlugin extends DialoguePlugin {
|
||||
|
||||
public SimpleDialoguePlugin() {
|
||||
|
||||
}
|
||||
|
||||
public SimpleDialoguePlugin(Player player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getIds() {
|
||||
return new int[] { 70099 };
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(int interfaceId, int buttonId) {
|
||||
end();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DialoguePlugin newInstance(Player player) {
|
||||
return new SimpleDialoguePlugin(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean open(Object... args) {
|
||||
String[] messages = new String[args.length];
|
||||
for (int i = 0; i < messages.length; i++)
|
||||
messages[i] = (String) args[i];
|
||||
interpreter.sendDialogue(messages);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package core.game.dialogue;
|
||||
|
||||
import core.plugin.Initializable;
|
||||
import core.game.node.entity.player.Player;
|
||||
|
||||
/**
|
||||
* Handles the SimpleEntityMessage dialogue.
|
||||
* @author 'Vexia
|
||||
*/
|
||||
@Initializable
|
||||
public class SimpleEntityMessage extends DialoguePlugin {
|
||||
|
||||
public SimpleEntityMessage() {
|
||||
|
||||
}
|
||||
|
||||
public SimpleEntityMessage(Player player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getIds() {
|
||||
return new int[] { 8000 };
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(int interfaceId, int buttonId) {
|
||||
end();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DialoguePlugin newInstance(Player player) {
|
||||
|
||||
return new SimpleEntityMessage(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean open(Object... args) {
|
||||
String[] messages = new String[args.length];
|
||||
for (int i = 0; i < messages.length; i++)
|
||||
messages[i] = (String) args[i];
|
||||
interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, messages);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,338 @@
|
||||
package core.game.dialogue
|
||||
|
||||
import core.game.node.entity.player.Player
|
||||
import core.game.node.item.Item
|
||||
import core.net.packet.PacketRepository
|
||||
import core.net.packet.context.ChildPositionContext
|
||||
import core.net.packet.out.RepositionChild
|
||||
import core.tools.StringUtils
|
||||
|
||||
/**
|
||||
* Represents a skill dialogue handler class.
|
||||
* @author Vexia
|
||||
*/
|
||||
open class SkillDialogueHandler(
|
||||
/**
|
||||
* Represents the player.
|
||||
*/
|
||||
val player: Player,
|
||||
/**
|
||||
* Represents the skill dialogue type.
|
||||
*/
|
||||
val type: SkillDialogue?, vararg data: Any) {
|
||||
/**
|
||||
* Gets the player.
|
||||
* @return The player.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Gets the type.
|
||||
* @return The type.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Gets the passed data.
|
||||
* @return the data.
|
||||
*/
|
||||
/**
|
||||
* Represents the object data passed through.
|
||||
*/
|
||||
val data: Array<Any>
|
||||
|
||||
/**
|
||||
* Method used to open a skill dialogue.
|
||||
*/
|
||||
fun open() {
|
||||
player.dialogueInterpreter.open(SKILL_DIALOGUE, this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to display the content on the dialogue.
|
||||
*/
|
||||
fun display() {
|
||||
if (type == null) {
|
||||
player.debug("Error! Type is null.")
|
||||
return
|
||||
}
|
||||
type.display(player, this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to create a product.
|
||||
* @param amount the amount.
|
||||
* @param index the index.
|
||||
*/
|
||||
open fun create(amount: Int, index: Int) {}
|
||||
|
||||
/**
|
||||
* Gets the total amount of items to be made.
|
||||
* @param index the index.
|
||||
* @return the amount.
|
||||
*/
|
||||
open fun getAll(index: Int): Int {
|
||||
return player.inventory.getAmount(data[0] as Item)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name.
|
||||
* @param item the item.
|
||||
* @return the name.
|
||||
*/
|
||||
protected open fun getName(item: Item): String {
|
||||
return StringUtils.formatDisplayName(item.name.replace("Unfired", ""))
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a skill dialogue type.
|
||||
* @author 'Vexia
|
||||
*/
|
||||
enum class SkillDialogue
|
||||
/**
|
||||
* Constructs a new `SkillDialogue` `Object`.
|
||||
* @param interfaceId the interface id.
|
||||
* @param base the base button.
|
||||
* @param length the length.
|
||||
*/(
|
||||
/**
|
||||
* Represents the interface id.
|
||||
*/
|
||||
val interfaceId: Int,
|
||||
/**
|
||||
* Represents the base button.
|
||||
*/
|
||||
private val baseButton: Int,
|
||||
/**
|
||||
* Represents the length.
|
||||
*/
|
||||
private val length: Int) {
|
||||
ONE_OPTION(309, 5, 1) {
|
||||
override fun display(player: Player, handler: SkillDialogueHandler) {
|
||||
val item = handler.data[0] as Item
|
||||
player.packetDispatch.sendString("<br><br><br><br>" + item.name, 309, 6)
|
||||
player.packetDispatch.sendItemZoomOnInterface(item.id, 160, 309, 2)
|
||||
PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, 309, 6, 60, 20))
|
||||
PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, 309, 2, 210, 30))
|
||||
}
|
||||
|
||||
override fun getAmount(handler: SkillDialogueHandler, buttonId: Int): Int {
|
||||
return when(buttonId){
|
||||
5 -> 1
|
||||
4 -> 5
|
||||
3 -> -1 //-1 is used to prompt an "enter an amount"
|
||||
else -> handler.getAll(getIndex(handler, buttonId))
|
||||
}
|
||||
}
|
||||
},
|
||||
TWO_OPTION(303, 7, 2) {
|
||||
override fun display(player: Player, handler: SkillDialogueHandler) {
|
||||
var item: Item
|
||||
player.interfaceManager.openChatbox(306)
|
||||
for (i in handler.data.indices) {
|
||||
item = handler.data[i] as Item
|
||||
player.packetDispatch.sendString("<br><br><br><br>" + handler.getName(item), 303, 7 + i)
|
||||
player.packetDispatch.sendItemZoomOnInterface(item.id, 160, 303, 2 + i)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getIndex(handler: SkillDialogueHandler?, buttonId: Int): Int {
|
||||
when (buttonId) {
|
||||
6, 5, 4, 3 -> return 0
|
||||
10, 9, 8, 7 -> return 1
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
override fun getAmount(handler: SkillDialogueHandler, buttonId: Int): Int {
|
||||
when (buttonId) {
|
||||
6, 10 -> return 1
|
||||
5, 9 -> return 5
|
||||
4, 8 -> return 10
|
||||
3, 7 -> return -1
|
||||
}
|
||||
return 1
|
||||
}
|
||||
},
|
||||
THREE_OPTION(304, 8, 3) {
|
||||
override fun display(player: Player, handler: SkillDialogueHandler) {
|
||||
var item: Item? = null
|
||||
for (i in 0..2) {
|
||||
item = handler.data[i] as Item
|
||||
player.packetDispatch.sendItemZoomOnInterface(item.id, 135, 304, 2 + i)
|
||||
player.packetDispatch.sendString("<br><br><br><br>" + item!!.name, 304, 304 - 296 + i * 4)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getIndex(handler: SkillDialogueHandler?, buttonId: Int): Int {
|
||||
when (buttonId) {
|
||||
7, 6, 5, 4 -> return 0
|
||||
11, 10, 9, 8 -> return 1
|
||||
15, 14, 13, 12 -> return 2
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
override fun getAmount(handler: SkillDialogueHandler, buttonId: Int): Int {
|
||||
when (buttonId) {
|
||||
7, 11, 15 -> return 1
|
||||
6, 10, 14 -> return 5
|
||||
5, 9, 13 -> return 10
|
||||
4, 8, 12 -> return -1
|
||||
}
|
||||
return 1
|
||||
}
|
||||
},
|
||||
FOUR_OPTION(305, 9, 4) {
|
||||
override fun display(player: Player, handler: SkillDialogueHandler) {
|
||||
var item: Item? = null
|
||||
for (i in 0..3) {
|
||||
item = handler.data[i] as Item
|
||||
player.packetDispatch.sendItemZoomOnInterface(item!!.id, 135, 305, 2 + i)
|
||||
player.packetDispatch.sendString("<br><br><br><br>" + item.name, 305, 305 - 296 + i * 4)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getIndex(handler: SkillDialogueHandler?, buttonId: Int): Int {
|
||||
when (buttonId) {
|
||||
5, 8, 6, 7 -> return 0
|
||||
9, 10, 11, 12 -> return 1
|
||||
13, 14, 15, 16 -> return 2
|
||||
17, 18, 19, 20 -> return 3
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
override fun getAmount(handler: SkillDialogueHandler, buttonId: Int): Int {
|
||||
when (buttonId) {
|
||||
8, 12, 16, 20 -> return 1
|
||||
7, 11, 15, 19 -> return 5
|
||||
6, 10, 14, 18 -> return 10
|
||||
5, 9, 13, 17 -> return -1
|
||||
}
|
||||
return 1
|
||||
}
|
||||
},
|
||||
FIVE_OPTION(306, 7, 5) {
|
||||
/**
|
||||
* Represents the position data.
|
||||
*/
|
||||
private val positions = arrayOf(intArrayOf(10, 30), intArrayOf(117, 10), intArrayOf(217, 20), intArrayOf(317, 15), intArrayOf(408, 15))
|
||||
override fun display(player: Player, handler: SkillDialogueHandler) {
|
||||
var item: Item
|
||||
player.interfaceManager.openChatbox(306)
|
||||
for (i in handler.data.indices) {
|
||||
item = handler.data[i] as Item
|
||||
player.packetDispatch.sendString("<br><br><br><br>" + handler.getName(item), 306, 10 + 4 * i)
|
||||
player.packetDispatch.sendItemZoomOnInterface(item.id, 160, 306, 2 + i)
|
||||
PacketRepository.send(RepositionChild::class.java, ChildPositionContext(player, 306, 2 + i, positions[i][0], positions[i][1]))
|
||||
}
|
||||
}
|
||||
|
||||
override fun getIndex(handler: SkillDialogueHandler?, buttonId: Int): Int {
|
||||
when (buttonId) {
|
||||
9, 8, 7, 6 -> return 0
|
||||
13, 12, 11, 10 -> return 1
|
||||
17, 16, 15, 14 -> return 2
|
||||
21, 20, 19, 18 -> return 3
|
||||
25, 24, 23, 22 -> return 4
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
override fun getAmount(handler: SkillDialogueHandler, buttonId: Int): Int {
|
||||
when (buttonId) {
|
||||
9, 13, 17, 21, 25 -> return 1
|
||||
8, 12, 16, 20, 24 -> return 5
|
||||
7, 11, 15, 19, 23 -> return 10
|
||||
6, 10, 14, 18, 22 -> return -1
|
||||
}
|
||||
return 1
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the interfaceId.
|
||||
* @return The interfaceId.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Method used to display the content for this type.
|
||||
* @param player the player.
|
||||
* @param handler the handler.
|
||||
*/
|
||||
open fun display(player: Player, handler: SkillDialogueHandler) {}
|
||||
|
||||
/**
|
||||
* Gets the amount.
|
||||
* @param handler the handler.
|
||||
* @param buttonId the buttonId.
|
||||
* @return the amount.
|
||||
*/
|
||||
open fun getAmount(handler: SkillDialogueHandler, buttonId: Int): Int {
|
||||
for (k in 0..3) {
|
||||
for (i in 0 until length) {
|
||||
val `val` = baseButton - k + 4 * i
|
||||
if (`val` == buttonId) {
|
||||
return if (k == 13) 1 else if (k == 8) 5 else if (k == 7) 10 else 6
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index selected.
|
||||
* @param handler the handler.
|
||||
* @param buttonId the buttonId.
|
||||
* @return the index selected.
|
||||
*/
|
||||
open fun getIndex(handler: SkillDialogueHandler?, buttonId: Int): Int {
|
||||
var index = 0
|
||||
for (k in 0..3) {
|
||||
for (i in 1 until length) {
|
||||
val `val` = baseButton + k + 4 * i
|
||||
if (`val` == buttonId) {
|
||||
return index + 1
|
||||
} else if (`val` <= buttonId) {
|
||||
index++
|
||||
}
|
||||
}
|
||||
index = 0
|
||||
}
|
||||
return index
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Gets the type for the length.
|
||||
* @param length2 the length to compare.
|
||||
* @return the type.
|
||||
*/
|
||||
fun forLength(length2: Int): SkillDialogue? {
|
||||
for (dial in values()) {
|
||||
if (dial.length == length2) {
|
||||
return dial
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Represents the skill dialogue id.
|
||||
*/
|
||||
const val SKILL_DIALOGUE = 3 shl 16
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new `SkillDialogueHandler` `Object`.
|
||||
* @param player the player.
|
||||
* @param type the type.
|
||||
* @param data the data.
|
||||
*/
|
||||
init {
|
||||
this.data = data as Array<Any>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package core.game.dialogue;
|
||||
|
||||
import static core.api.ContentAPIKt.*;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.plugin.Initializable;
|
||||
import kotlin.Unit;
|
||||
|
||||
/**
|
||||
* Represents the dialogue plugin used to automatically handle skill dialogues with creation amounts.
|
||||
* @author Vexia
|
||||
*
|
||||
*/
|
||||
@Initializable
|
||||
public class SkillDialoguePlugin extends DialoguePlugin {
|
||||
|
||||
/**
|
||||
* Represents the skill dialogue handler.
|
||||
*/
|
||||
private SkillDialogueHandler handler;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code SkillDialogue} {@code Object}.
|
||||
*/
|
||||
public SkillDialoguePlugin() {
|
||||
/**
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code SkillDialogue} {@code Object}.
|
||||
* @param player the player.
|
||||
*/
|
||||
public SkillDialoguePlugin(final Player player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DialoguePlugin newInstance(Player player) {
|
||||
return new SkillDialoguePlugin(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean open(Object... args) {
|
||||
handler = (SkillDialogueHandler) args[0];
|
||||
handler.display();
|
||||
player.getInterfaceManager().openChatbox(handler.getType().getInterfaceId());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(int interfaceId, int buttonId) {
|
||||
final int amount = handler.getType().getAmount(handler, buttonId);
|
||||
final int index = handler.getType().getIndex(handler, buttonId);
|
||||
end();
|
||||
if (amount != -1) {
|
||||
handler.create(amount, index);
|
||||
} else {
|
||||
sendInputDialogue(player, true, "Enter the amount:", (value) -> {
|
||||
if (value instanceof String) {
|
||||
handler.create(Integer.parseInt((String) value), index);
|
||||
} else {
|
||||
handler.create((int) value, index);
|
||||
}
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getIds() {
|
||||
return new int[] { SkillDialogueHandler.SKILL_DIALOGUE };
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
package core.game.dialogue.book;
|
||||
|
||||
import core.game.component.Component;
|
||||
import core.game.dialogue.DialoguePlugin;
|
||||
import core.game.dialogue.DialoguePlugin;
|
||||
import core.game.node.entity.player.Player;
|
||||
import core.plugin.PluginManifest;
|
||||
import core.plugin.PluginType;
|
||||
|
||||
/**
|
||||
* Represents a dialogue book.
|
||||
* @author 'Vexia
|
||||
* @date 1/1/14
|
||||
*/
|
||||
@PluginManifest(type = PluginType.DIALOGUE)
|
||||
public abstract class Book extends DialoguePlugin {
|
||||
|
||||
/**
|
||||
* Represents the component interface of the book.
|
||||
*/
|
||||
private static final Component INTERFACE = new Component(49);
|
||||
|
||||
/**
|
||||
* Represents the red string.
|
||||
*/
|
||||
protected static final String RED = "<col=8A0808>";
|
||||
|
||||
/**
|
||||
* Represents the blue string.
|
||||
*/
|
||||
protected static final String BLUE = "<col=08088A>";
|
||||
|
||||
/**
|
||||
* Represents the name of the book.
|
||||
*/
|
||||
protected String name;
|
||||
|
||||
/**
|
||||
* Represents the id of this book.
|
||||
*/
|
||||
protected int id;
|
||||
|
||||
/**
|
||||
* Represents the pages of this book.
|
||||
*/
|
||||
protected PageSet[] sets;
|
||||
|
||||
/**
|
||||
* Represents the index of the page set we're at.
|
||||
*/
|
||||
protected int index = -1;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code Book} {@code Object}.
|
||||
* @param name the name.
|
||||
* @param id the id.
|
||||
*/
|
||||
public Book(final Player player, final String name, final int id, final PageSet... sets) {
|
||||
this.player = player;
|
||||
this.name = name;
|
||||
this.id = id;
|
||||
this.sets = sets;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code Book} {@code Object}.
|
||||
*/
|
||||
public Book() {
|
||||
/**
|
||||
* empty.
|
||||
*/
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean open(Object... args) {
|
||||
return open(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(int interfaceId, int buttonId) {
|
||||
switch (buttonId) {
|
||||
case 112:
|
||||
player.getInterfaceManager().close();
|
||||
break;
|
||||
case 66:
|
||||
case 52:
|
||||
next();
|
||||
break;
|
||||
case 64:
|
||||
case 50:
|
||||
previous();
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object fireEvent(String identifier, Object... args) {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to open a book.
|
||||
* @return <code>True</code> if succesfully opened.
|
||||
*/
|
||||
public boolean open(final Player player) {
|
||||
next();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to write the next dialogue.
|
||||
*/
|
||||
public void next() {
|
||||
player.lock();
|
||||
index++;
|
||||
if (index > sets.length - 1) {
|
||||
player.unlock();
|
||||
player.getInterfaceManager().close();
|
||||
return;
|
||||
}
|
||||
final Page[] set = sets[index].getPages();
|
||||
display(set);
|
||||
player.unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to write the previous dialogue.
|
||||
*/
|
||||
public void previous() {
|
||||
player.lock();
|
||||
index--;
|
||||
if (index < 0) {
|
||||
index = 0;
|
||||
}
|
||||
final Page[] set = sets[index].getPages();
|
||||
display(set);
|
||||
player.unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to display a set of pages.
|
||||
* @param set the set.
|
||||
*/
|
||||
public void display(Page[] set) {
|
||||
// TODO: It seems like different subclasses instantiate this by
|
||||
// copy-paste, this should probably be made final, and should switch between a few
|
||||
// implementations by component id
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used when the book is finished.
|
||||
*/
|
||||
public void finish() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name.
|
||||
* @return The name.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the id.
|
||||
* @return The id.
|
||||
*/
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index.
|
||||
* @return The index.
|
||||
*/
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the index.
|
||||
* @param index The index to set.
|
||||
*/
|
||||
public void setIndex(int index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the interface component.
|
||||
* @return the component.
|
||||
*/
|
||||
public Component getInterface() {
|
||||
return INTERFACE;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package core.game.dialogue.book;
|
||||
|
||||
/**
|
||||
* Represents a book line.
|
||||
* @author 'Vexia
|
||||
* @date 31/12/2013
|
||||
*/
|
||||
public class BookLine {
|
||||
|
||||
/**
|
||||
* Represents the message to display.
|
||||
*/
|
||||
private final String message;
|
||||
|
||||
/**
|
||||
* Represents the child if of the line.
|
||||
*/
|
||||
private final int child;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code Page} {@code Object}.
|
||||
* @param message the message.
|
||||
* @param child the child.
|
||||
*/
|
||||
public BookLine(final String message, final int child) {
|
||||
this.message = message;
|
||||
this.child = child;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message.
|
||||
* @return The message.
|
||||
*/
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the child.
|
||||
* @return The child.
|
||||
*/
|
||||
public int getChild() {
|
||||
return child;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package core.game.dialogue.book;
|
||||
|
||||
/**
|
||||
* Represents a page on a book.
|
||||
* @author 'Vexia
|
||||
* @date 1/1/14
|
||||
*/
|
||||
public class Page {
|
||||
|
||||
/**
|
||||
* Represents the lines on a page.
|
||||
*/
|
||||
private final BookLine[] lines;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code Page} {@code Object}.
|
||||
* @param lines the lines.
|
||||
*/
|
||||
public Page(BookLine... lines) {
|
||||
this.lines = lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the lines.
|
||||
* @return The lines.
|
||||
*/
|
||||
public BookLine[] getLines() {
|
||||
return lines;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package core.game.dialogue.book;
|
||||
|
||||
/**
|
||||
* Represents a set of pages on a book.
|
||||
* @author 'Vexia
|
||||
*/
|
||||
public class PageSet {
|
||||
|
||||
/**
|
||||
* Represents the set of pages.
|
||||
*/
|
||||
private final Page[] pages;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code PageSet} {@code Object}.
|
||||
* @param pages the pages.
|
||||
*/
|
||||
public PageSet(final Page... pages) {
|
||||
this.pages = pages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the pages.
|
||||
* @return The pages.
|
||||
*/
|
||||
public Page[] getPages() {
|
||||
return pages;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user