Implemented Recruitment Drive quest

This commit is contained in:
Oven Bread
2024-08-21 14:04:44 +00:00
committed by Ryan
parent 29fa9a5a21
commit e25c7d7824
28 changed files with 2715 additions and 181 deletions
+20
View File
@@ -919,6 +919,14 @@ fun openDialogue(player: Player, dialogue: Any, vararg args: Any) {
}
}
/**
* Closes any opened dialogue.
*/
fun closeDialogue(player: Player) {
player.dialogueInterpreter.close()
player.interfaceManager.closeChatbox()
}
/**
* Gets an NPC with the given ID from the repository.
* @param id the ID of the NPC to locate
@@ -1647,6 +1655,18 @@ fun sendNPCDialogue(player: Player, npc: Int, msg: String, expr: core.game.dialo
player.dialogueInterpreter.sendDialogues(npc, expr, *splitLines(msg))
}
/**
* Sends a dialogue that uses the player's chathead.
* @param player the player to send the dialogue to
* @param npc the ID of the NPC to use for the chathead
* @param expr the FacialExpression to use. An enum exists for these called FacialExpression.
* @param msg the message to send.
*/
fun sendNPCDialogueLines(player: Player, npc: Int, expr: core.game.dialogue.FacialExpression, hideContinue: Boolean, vararg msgs: String) {
val dialogueComponent = player.dialogueInterpreter.sendDialogues(npc, expr, *msgs)
player.packetDispatch.sendInterfaceConfig(dialogueComponent.id, msgs.size + 4, hideContinue)
}
/**
* Sends an animation to a specific interface child
* @param player the player to send the packet to
@@ -121,6 +121,29 @@ abstract class Cutscene(val player: Player) {
player.dialogueInterpreter.addAction { _,_ -> onContinue.invoke() }
}
/**
* Sends a dialogue to the player using the given NPC ID, which updates the cutscene stage by default when continued.
* @param npcId the ID of the NPC to send a dialogue for
* @param expression the FacialExpression the NPC should use
* @param message the message to send
* @param onContinue (optional) a method that runs when the dialogue is "continued." Increments the cutscene stage by default.
*/
fun dialogueLinesUpdate(npcId: Int, expression: core.game.dialogue.FacialExpression, vararg message: String, onContinue: () -> Unit = {incrementStage()})
{
logCutscene("Sending NPC dialogue lines update.")
sendNPCDialogueLines(player, npcId, expression, true, *message)
player.dialogueInterpreter.addAction { _,_ -> onContinue.invoke() }
}
/**
* Forces the dialogue to close.
*/
fun dialogueClose()
{
logCutscene("Sending dialogue close.")
closeDialogue(player)
}
/**
* Sends a non-NPC dialogue to the player, which updates the cutscene stage by default when continued
* @param message the message to send
@@ -248,6 +271,51 @@ abstract class Cutscene(val player: Player) {
AntiMacro.pause(player)
}
/**
* Ends this cutscene, teleporting the player to the exit location, and then fading it back in and executing the endActions passed to this method.
* @param endActions (optional) a method that executes when the cutscene fully completes
*/
fun endWithoutFade(endActions: (() -> Unit)? = null)
{
ended = true
GameWorld.Pulser.submit(object : Pulse(){
var tick: Int = 0
override fun pulse(): Boolean {
when(tick++)
{
0 -> player.properties.teleportLocation = exitLocation
1 -> {
return true
}
}
return false
}
override fun stop() {
super.stop()
player ?: return
player.removeAttribute(ATTRIBUTE_CUTSCENE)
player.removeAttribute(ATTRIBUTE_CUTSCENE_STAGE)
player.properties.isSafeZone = false
player.properties.safeRespawn = ServerConstants.HOME_LOCATION
player.interfaceManager.restoreTabs()
player.unlock()
clearNPCs()
player.unhook(CUTSCENE_DEATH_HOOK)
player.logoutListeners.remove("cutscene")
AntiMacro.unpause(player)
PacketRepository.send(MinimapState::class.java, MinimapStateContext(player, 0))
try {
endActions?.invoke()
} catch (e: Exception) {
log(this::class.java, Log.ERR, "There's some bad nasty code in ${this::class.java.simpleName} end actions!")
e.printStackTrace()
}
}
})
}
/**
* Ends this cutscene, fading the screen to black, teleporting the player to the exit location, and then fading it back in and executing the endActions passed to this method.
* @param fade (optional) should the cutscene fade to black?
@@ -295,6 +295,14 @@ class DialogueBuilder(var target: DialogueBuilderFile, var clauseIndex: Int = -1
}
}
/**
* The first if-statement to a dialogue. At minimum, you must have "b.onPredicate { _ -> true }"
* PLEASE BE CAREFUL ABOUT HAVING COMPLEX PREDICATE.
* If at any point during a dialogue that the predicate is not satisfied,
* it will block further dialogue progression and any dialogue will suddenly disappear.
* e.g. onPredicate(x==2) but during dialogue you set x=3, dialogue after it will disappear.
* Think of this as a repeated filter at every dialogue step.
*/
fun onPredicate(predicate: (player: Player) -> Boolean): DialogueBuilder {
target.data.add(DialogueClause(predicate, ArrayList()))
clauseIndex = target.data.size - 1
@@ -10,6 +10,7 @@ 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.game.world.GameWorld;
import core.net.packet.PacketRepository;
import core.net.packet.context.ChildPositionContext;
import core.net.packet.context.ContainerContext;
@@ -501,6 +502,7 @@ public final class DialogueInterpreter {
static Pattern GENDERED_SUBSTITUTION = Pattern.compile("@g\\[([^,]*),([^\\]]*)\\]");
public static String doSubstitutions(Player player, String msg) {
msg = msg.replace("@name", player.getUsername());
msg = msg.replace("@servername", GameWorld.getSettings().getName());
StringBuilder sb = new StringBuilder();
Matcher m = GENDERED_SUBSTITUTION.matcher(msg);
int index = player.isMale() ? 1 : 2;