diff --git a/Server/data/configs/npc_configs.json b/Server/data/configs/npc_configs.json
index dce10e733..dfe1a42bc 100644
--- a/Server/data/configs/npc_configs.json
+++ b/Server/data/configs/npc_configs.json
@@ -72624,5 +72624,65 @@
"examine": "An intelligent-looking shop owner.",
"name": "Obli",
"id": "516"
+ },
+ {
+ "examine": "A person sitting an exam.",
+ "melee_animation": "0",
+ "range_animation": "0",
+ "defence_animation": "0",
+ "magic_animation": "0",
+ "death_animation": "0",
+ "name": "Student",
+ "defence_level": "1",
+ "lifepoints": "10",
+ "strength_level": "1",
+ "id": "7151",
+ "range_level": "1",
+ "attack_level": "1"
+ },
+ {
+ "examine": "A person sitting an exam.",
+ "melee_animation": "0",
+ "range_animation": "0",
+ "defence_animation": "0",
+ "magic_animation": "0",
+ "death_animation": "0",
+ "name": "Student",
+ "defence_level": "1",
+ "lifepoints": "10",
+ "strength_level": "1",
+ "id": "7153",
+ "range_level": "1",
+ "attack_level": "1"
+ },
+ {
+ "examine": "A person sitting an exam.",
+ "melee_animation": "0",
+ "range_animation": "0",
+ "defence_animation": "0",
+ "magic_animation": "0",
+ "death_animation": "0",
+ "name": "Student",
+ "defence_level": "1",
+ "lifepoints": "10",
+ "strength_level": "1",
+ "id": "7154",
+ "range_level": "1",
+ "attack_level": "1"
+ },
+ {
+ "examine": "A person sitting an exam.",
+ "melee_animation": "0",
+ "range_animation": "0",
+ "defence_animation": "0",
+ "magic_animation": "0",
+ "death_animation": "0",
+ "name": "Student",
+ "defence_level": "1",
+ "lifepoints": "10",
+ "strength_level": "1",
+ "id": "7155",
+ "range_level": "1",
+ "attack_level": "1"
}
]
\ No newline at end of file
diff --git a/Server/data/configs/npc_spawns.json b/Server/data/configs/npc_spawns.json
index 57a3f2c37..044b5aec7 100644
--- a/Server/data/configs/npc_spawns.json
+++ b/Server/data/configs/npc_spawns.json
@@ -11389,11 +11389,11 @@
},
{
"npc_id": "7159",
- "loc_data": "{3174,4238,2,1,6}-{3175,4243,2,1,6}-{3179,4236,2,1,4}-{3145,4272,1,1,3}-{3145,4276,1,1,3}-{3152,4271,1,1,6}-{3144,4264,1,1,4}-{3153,4266,1,1,1}-{3152,4261,1,1,4}-{3145,4259,1,1,6}-{3161,4259,1,1,0}-{3160,4265,1,1,0}-{3153,4246,1,1,3}-{3157,4248,1,1,6}-{3161,4247,1,1,4}-{3146,4247,1,1,6}-{3153,4233,1,1,4}-{3153,4240,1,1,6}-{3155,4238,1,1,5}-{3169,4267,3,1,3}-{3160,4265,3,1,6}-{3168,4250,3,1,4}-{3168,4244,3,1,6}-{3160,4239,3,1,1}-{3160,4228,3,1,3}-{3147,4225,3,1,3}-{3145,4242,3,1,5}-{3139,4249,3,1,6}-{3144,4253,3,1,3}-{3145,4266,3,1,0}-{3138,4266,3,1,3}-"
+ "loc_data": "{3174,4238,2,1,6}-{3175,4243,2,1,6}-{3179,4236,2,1,4}-{3145,4272,1,1,3}-{3145,4276,1,1,3}-{3152,4271,1,1,6}-{3144,4264,1,1,4}-{3153,4266,1,1,1}-{3152,4261,1,1,4}-{3145,4259,1,1,6}-{3161,4259,1,1,0}-{3160,4265,1,1,0}-{3153,4246,1,1,3}-{3157,4248,1,1,6}-{3161,4247,1,1,4}-{3146,4247,1,1,6}-{3153,4233,1,1,4}-{3153,4240,1,1,6}-{3155,4238,1,1,5}-{3169,4267,3,1,3}-{3160,4265,3,1,6}-{3168,4250,3,1,4}-{3168,4244,3,1,6}-{3160,4239,3,1,1}-{3160,4228,3,1,3}-{3147,4225,3,1,3}-{3145,4242,3,1,5}-{3139,4249,3,1,6}-{3144,4253,3,1,3}-{3145,4266,3,1,0}-{3138,4266,3,1,3}-{3151,4272,3,1,0}-{3139,4272,3,1,0}-{3146,4231,3,1,0}-{3169,4270,3,1,0}-"
},
{
"npc_id": "7160",
- "loc_data": "{3175,4254,2,1,7}-{3176,4247,2,1,5}-{3174,4269,2,1,1}-{3190,4253,2,1,3}-{3192,4247,2,1,3}-{3189,4235,2,1,0}-{3152,4269,0,1,4}-{3160,4278,0,1,1}-{3160,4262,0,1,3}-{3149,4250,0,1,0}-{3158,4250,0,1,5}-{3161,4236,0,1,6}-{3172,4250,0,1,2}-{3171,4269,3,1,1}-{3157,4277,3,1,3}-{3150,4278,3,1,3}-"
+ "loc_data": "{3175,4254,2,1,7}-{3176,4247,2,1,5}-{3174,4269,2,1,1}-{3190,4253,2,1,3}-{3192,4247,2,1,3}-{3189,4235,2,1,0}-{3152,4269,0,1,4}-{3160,4278,0,1,1}-{3160,4262,0,1,3}-{3149,4250,0,1,0}-{3158,4250,0,1,5}-{3161,4236,0,1,6}-{3172,4250,0,1,2}-{3171,4269,3,1,1}-{3157,4277,3,1,3}-{3150,4278,3,1,3}-{3160,4271,1,1,0}-{3163,4274,1,1,0}-{3167,4277,1,1,0}-{3173,4277,1,1,0}-{3175,4275,1,1,0}-{3160,4269,0,1,0}-{3173,4264,0,1,0}-{3190,4237,2,1,0}-{3154,4279,3,1,0}-"
},
{
"npc_id": "7161",
diff --git a/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/GuardDialogue.kt b/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/GuardDialogue.kt
new file mode 100644
index 000000000..0fc1f9dd7
--- /dev/null
+++ b/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/GuardDialogue.kt
@@ -0,0 +1,164 @@
+package content.region.misthalin.barbvillage.stronghold.playersafety
+
+import core.api.runTask
+import core.game.dialogue.DialoguePlugin
+import core.game.dialogue.FacialExpression
+import core.game.node.entity.player.Player
+import core.game.world.GameWorld.settings
+import core.plugin.Initializable
+import core.tools.END_DIALOGUE
+import core.tools.START_DIALOGUE
+import org.rs09.consts.NPCs
+
+@Initializable
+class GuardDialogue(player: Player? = null) : DialoguePlugin(player) {
+
+ companion object{
+ const val DIALOGUE_COMPLETED = START_DIALOGUE
+ const val DIALOGUE_NOT_COMPLETED = 50
+
+ }
+
+ override fun open(vararg args: Any?): Boolean {
+ val hasRead = player.savedData.globalData.hasReadPlaques()
+ if (hasRead) {
+ npcl(FacialExpression.HALF_GUILTY, "Can I help you?").also { stage = DIALOGUE_COMPLETED }
+ }
+ else {
+ npcl(FacialExpression.FURIOUS, "Ahem! Can I help you?").also { stage = DIALOGUE_NOT_COMPLETED }
+ }
+ return true
+ }
+
+ override fun handle(interfaceId: Int, buttonId: Int): Boolean {
+ when (stage) {
+ DIALOGUE_COMPLETED -> {
+ playerl(
+ FacialExpression.HALF_GUILTY, "Can I go upstairs?"
+ ).also { stage++ }
+ }
+
+ DIALOGUE_COMPLETED + 1 -> {
+ npcl(
+ FacialExpression.FURIOUS,
+ "Yes, citizen. Before you do I am instructed to give " +
+ "you one final piece of information"
+ ).also { stage++ }
+ }
+
+ DIALOGUE_COMPLETED + 2 -> {
+ playerl(FacialExpression.HALF_GUILTY, "Oh, okay then.").also { stage++ }
+ }
+
+ DIALOGUE_COMPLETED + 3 -> {
+ npcl(
+ FacialExpression.HALF_GUILTY,
+ "In your travels around " + settings!!.name + ", should you find a player who acts in a " +
+ "way that breaks on of our rules, you should report them."
+ ).also { stage++ }
+ }
+
+ DIALOGUE_COMPLETED + 4 -> {
+ npcl(
+ FacialExpression.HALF_GUILTY,
+ "Reporting is very simple and easy to do. Simply click the Report Abuse button at " +
+ "the bottom of the screen and you will be shown the following screen:"
+ ).also { stage++ }
+ }
+
+ DIALOGUE_COMPLETED + 5 -> {
+ player.interfaceManager.openComponent(700)
+ runTask(player, 5) {
+ if (player != null) {
+ player.interfaceManager.close()
+ }
+ return@runTask
+ }.also { stage++ }
+ }
+
+ DIALOGUE_COMPLETED + 6 -> {
+ npcl(
+ FacialExpression.HALF_GUILTY,
+ "Simply enter the player's name in the box and click the rule that the offender was breaking."
+ ).also { stage++ }
+ }
+
+ DIALOGUE_COMPLETED + 7 -> {
+ playerl(FacialExpression.HALF_GUILTY, "Okay. Then what?").also { stage++ }
+ }
+
+ DIALOGUE_COMPLETED + 8 -> {
+ npcl(
+ FacialExpression.HALF_GUILTY,
+ "That's it! It really is that simple and it only takes a moment to do. " +
+ "Now you may enter the training centre. Good luck, citizen."
+ ).also { stage++ }
+ }
+
+ DIALOGUE_COMPLETED + 9 -> {
+ playerl(FacialExpression.HALF_GUILTY, "Thanks!").also { stage = END_DIALOGUE }
+ }
+
+ DIALOGUE_NOT_COMPLETED -> {
+ playerl(
+ FacialExpression.HALF_GUILTY, "I'd like to go up to the training centre please."
+ ).also { stage++ }
+ }
+ DIALOGUE_NOT_COMPLETED + 1 -> {
+ npcl(FacialExpression.FURIOUS, "Sorry, citizen, you can't go up there.").also { stage++ }
+ }
+ DIALOGUE_NOT_COMPLETED + 2 -> {
+ playerl(FacialExpression.OLD_SNEAKY, "Why not?").also { stage++ }
+
+ }
+ DIALOGUE_NOT_COMPLETED + 3 -> {
+ npcl(
+ FacialExpression.ANNOYED,
+ "You must learn about player safety before entering the training centre."
+ ).also { stage++ }
+ }
+ DIALOGUE_NOT_COMPLETED + 4 -> {
+ playerl(FacialExpression.HALF_GUILTY, "Oh. How do I do that?").also { stage++ }
+ }
+ DIALOGUE_NOT_COMPLETED + 5 -> {
+ npcl(
+ FacialExpression.HALF_GUILTY,
+ "Each of these gublinches have been caught breaking the rules of " + settings!!.name + ". " +
+ "You should read the plaques on each of their cells to learn what they did wrong."
+ ).also { stage++ }
+
+ }
+ DIALOGUE_NOT_COMPLETED + 6 -> {
+ playerl(
+ FacialExpression.HALF_GUILTY,
+ "Oh, right. I can enter the training centre once I have done that?"
+ ).also { stage++ }
+ }
+ DIALOGUE_NOT_COMPLETED + 7 -> {
+ npcl(
+ FacialExpression.HALF_GUILTY,
+ "Yes. Once you have have examined each of the plaques, come and speak to me " +
+ "and I will tell you about the Report Abuse function."
+ ).also { stage++ }
+ }
+ DIALOGUE_NOT_COMPLETED + 8 -> {
+ npcl(
+ FacialExpression.HALF_GUILTY,
+ "After that, I can let you into the training centre, upstairs."
+ ).also { stage++ }
+ }
+ DIALOGUE_NOT_COMPLETED + 9 -> {
+ playerl(FacialExpression.HALF_GUILTY, "Okay, thanks for the help.").also { stage = END_DIALOGUE }
+ player.sendMessage("You need to read the jail plaques before the guard will allow you upstairs.")
+ }
+ }
+ return true
+
+ }
+
+ override fun getIds(): IntArray {
+ return intArrayOf(NPCs.GUARD_7142)
+ }
+
+
+}
\ No newline at end of file
diff --git a/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/GuardDialoguePlugin.java b/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/GuardDialoguePlugin.java
deleted file mode 100644
index 777ffcfa3..000000000
--- a/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/GuardDialoguePlugin.java
+++ /dev/null
@@ -1,144 +0,0 @@
-package content.region.misthalin.barbvillage.stronghold.playersafety;
-
-import core.game.component.Component;
-import core.game.dialogue.DialoguePlugin;
-import core.game.dialogue.FacialExpression;
-import core.game.node.entity.npc.NPC;
-import core.game.node.entity.player.Player;
-import core.tools.Log;
-import core.tools.SystemLogger;
-import core.game.system.task.Pulse;
-import core.game.world.GameWorld;
-
-import static core.api.ContentAPIKt.log;
-
-/**
- * @author Tyler Telis
- */
-public class GuardDialoguePlugin extends DialoguePlugin {
-
- /**
- * Constructs a new {@code GuardDialogue} instance.
- * @param player The {@code Player} instance.
- */
- public GuardDialoguePlugin(Player player) {
- super(player);
- }
-
- /**
- * Constructs a new {@code GuardDialoguePlugin} instance.
- */
- public GuardDialoguePlugin() {
- }
-
- @Override
- public DialoguePlugin newInstance(Player player) {
- return new GuardDialoguePlugin(player);
- }
-
- @Override
- public boolean open(Object... args) {
- npc = (NPC) args[0];
- boolean read = player.getSavedData().getGlobalData().hasReadPlaques();
- interpreter.sendDialogues(npc, read ? FacialExpression.HALF_GUILTY : FacialExpression.FURIOUS, read ? "Can I help you?" : "Ahem! Can I help you?");
- stage = 0;
- return true;
- }
-
- @Override
- public boolean handle(int interfaceId, int buttonId) {
- boolean read = player.getSavedData().getGlobalData().hasReadPlaques();
- switch (stage) {
- case -1:// END dialogue stage.
- end();
- break;
- case 0:
- interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, read ? "Can I go upstairs?" : "I'd like to go up to the training centre please.");
- increment();
- break;
- case 1:
- interpreter.sendDialogues(npc, FacialExpression.FURIOUS, !read ? "Sorry, citizen, you can't go up there." : "", "Yes, citizen. Before you do I am instructed to give", "you one final piece of information");
- increment();
- break;
- case 2:
- interpreter.sendDialogues(player, read ? FacialExpression.HALF_GUILTY : FacialExpression.OLD_SNEAKY, read ? "Oh, okay then." : "Why not?");
- increment();
- break;
- case 3:
- if (!read) {
- npc("You must learn about player safety before
entering the training centre.");
- } else {
- npc("In your travels around " + GameWorld.getSettings().getName() + ", should you find a", "player who acts in a way that breaks on of our rules,", "you should report them.");
- }
- increment();
- break;
- case 4:
- interpreter.sendDialogues(read ? npc : player, FacialExpression.HALF_GUILTY, !read ? "Oh. How do I do that?" : "Reporting is very simple and easy to do. Simply click", "the Report Abuse button at the bottom of the screen", "and you will be shown the following screen:");
- stage = read ? 10 : stage + 1;
- break;
- case 5:
- interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Each of these gublinches have been caught breaking the", "Rules of " + GameWorld.getSettings().getName() + ". You should read the plaques on", "each of their cells to learn what they did wrong.");
- increment();
- break;
- case 6:
- interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Oh, right. I can enter the training centre once I have", "done that?");
- increment();
- break;
- case 7:
- interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Yes. Once you have have examined each of the plaques,", "come and speak to me and I will tell you about the", "Report Abuse function.");
- increment();
- break;
- case 8:
- interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "After that, I can let you into the training centre,", "upstairs.");
- increment();
- break;
- case 9:
- interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Okay, thanks for the help.");
- player.getPacketDispatch().sendMessage("You need to read the jail plaques before the guard will allow you upstairs.");
- stage = -1;
- break;
- case 10:
- if (read) {
- player.getInterfaceManager().open(new Component(700));
- GameWorld.getPulser().submit(new Pulse(5) {
-
- @Override
- public boolean pulse() {
- if (player != null) {
- player.getInterfaceManager().close();
- }
- return true;
- }
-
- });
- stage = 12;
- }
- break;
- case 12:
- interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "Simply enter the player's name in the box and click the", "rule that the offender was breaking.");
- stage = 13;
- break;
- case 13:
- interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Okay. Then what?");
- stage = 14;
- break;
- case 14:
- interpreter.sendDialogues(npc, FacialExpression.HALF_GUILTY, "That's it! It reall is that simple and it only takes a ", "moment to do. Now you may enter the training", "centre. Good luck, citizen.");
- stage = 15;
- break;
- case 15:
- interpreter.sendDialogues(player, FacialExpression.HALF_GUILTY, "Thanks!");
- stage = -1;
- break;
- default:
- log(this.getClass(), Log.ERR, "Unhandled dialogue stage=" + stage);
- }
- return false;
- }
-
- @Override
- public int[] getIds() {
- return new int[] { 7142 };
- }
-
-}
diff --git a/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/PSOptionHandler.java b/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/PSOptionHandler.java
deleted file mode 100644
index 742b4be80..000000000
--- a/Server/src/main/content/region/misthalin/barbvillage/stronghold/playersafety/PSOptionHandler.java
+++ /dev/null
@@ -1,176 +0,0 @@
-package content.region.misthalin.barbvillage.stronghold.playersafety;
-
-import static content.region.misthalin.barbvillage.stronghold.playersafety.StrongHoldOfPlayerSafetyPlugin.JAIL_DOWN_STAIRS;
-import static content.region.misthalin.barbvillage.stronghold.playersafety.StrongHoldOfPlayerSafetyPlugin.JAIL_ENTRANCE_ID_ENTER;
-import static content.region.misthalin.barbvillage.stronghold.playersafety.StrongHoldOfPlayerSafetyPlugin.JAIL_ENTRANCE_LEAVE;
-import static content.region.misthalin.barbvillage.stronghold.playersafety.StrongHoldOfPlayerSafetyPlugin.JAIL_ENTRANCE_LOCATION_ENTER;
-import static content.region.misthalin.barbvillage.stronghold.playersafety.StrongHoldOfPlayerSafetyPlugin.JAIL_ENTRANCE_LOCATION_LEAVE;
-import static content.region.misthalin.barbvillage.stronghold.playersafety.StrongHoldOfPlayerSafetyPlugin.JAIL_STAIRS_DOWN;
-import static content.region.misthalin.barbvillage.stronghold.playersafety.StrongHoldOfPlayerSafetyPlugin.JAIL_STAIRS_UP;
-import static content.region.misthalin.barbvillage.stronghold.playersafety.StrongHoldOfPlayerSafetyPlugin.JAIL_UP_STAIRS;
-import static content.region.misthalin.barbvillage.stronghold.playersafety.StrongHoldOfPlayerSafetyPlugin.TEST_PAPER_ITEM_ID;
-import static content.region.misthalin.barbvillage.stronghold.playersafety.StrongHoldOfPlayerSafetyPlugin.forId;
-
-import core.cache.def.impl.ItemDefinition;
-import core.cache.def.impl.SceneryDefinition;
-import core.game.dialogue.DialogueAction;
-import core.game.global.action.DoorActionHandler;
-import core.game.interaction.OptionHandler;
-import core.game.node.Node;
-import core.game.node.entity.player.Player;
-import core.game.node.entity.player.link.emote.Emotes;
-import core.game.node.item.Item;
-import core.game.node.scenery.Scenery;
-import core.game.node.scenery.SceneryBuilder;
-import core.game.world.map.Location;
-import core.plugin.Plugin;
-
-import content.region.misthalin.barbvillage.stronghold.playersafety.StrongHoldOfPlayerSafetyPlugin.JailPlaques;
-
-import static core.api.ContentAPIKt.*;
-
-
-/**
- * @author Tyler Telis
- */
-public class PSOptionHandler extends OptionHandler {
-
- @Override
- public Plugin