From a2a634b7b51b4f61cfee310bd36608303bf1f12c Mon Sep 17 00:00:00 2001 From: Ceikry Date: Mon, 8 Mar 2021 02:50:36 -0600 Subject: [PATCH] Added NPC-based patch protection, TODO: flower-based protection --- .../game/content/dialogue/DialoguePlugin.java | 2 +- .../skill/farming/FarmerPayOptionHandler.kt | 135 ++++++++++++++++++ .../game/node/entity/skill/farming/Farmers.kt | 32 +++++ .../game/node/entity/skill/farming/Patch.kt | 3 +- .../state/newsys/states/FarmingState.kt | 3 + 5 files changed, 173 insertions(+), 2 deletions(-) create mode 100644 Server/src/main/java/Server/core/game/node/entity/skill/farming/FarmerPayOptionHandler.kt create mode 100644 Server/src/main/java/Server/core/game/node/entity/skill/farming/Farmers.kt diff --git a/Server/src/main/java/Server/core/game/content/dialogue/DialoguePlugin.java b/Server/src/main/java/Server/core/game/content/dialogue/DialoguePlugin.java index 22c12a1c8..a1e12367e 100644 --- a/Server/src/main/java/Server/core/game/content/dialogue/DialoguePlugin.java +++ b/Server/src/main/java/Server/core/game/content/dialogue/DialoguePlugin.java @@ -183,7 +183,7 @@ public abstract class DialoguePlugin implements Plugin { if (npc == null) { return interpreter.sendDialogues(getIds()[0], getIds()[0] > 8591 ? FacialExpression.OLD_NORMAL : FacialExpression.FRIENDLY, messages); } - return interpreter.sendDialogues(npc, getIds()[0] > 8591 ? FacialExpression.OLD_NORMAL : FacialExpression.FRIENDLY, messages); + return interpreter.sendDialogues(npc, npc.getId() > 8591 ? FacialExpression.OLD_NORMAL : FacialExpression.FRIENDLY, messages); } /** diff --git a/Server/src/main/java/Server/core/game/node/entity/skill/farming/FarmerPayOptionHandler.kt b/Server/src/main/java/Server/core/game/node/entity/skill/farming/FarmerPayOptionHandler.kt new file mode 100644 index 000000000..248dcf424 --- /dev/null +++ b/Server/src/main/java/Server/core/game/node/entity/skill/farming/FarmerPayOptionHandler.kt @@ -0,0 +1,135 @@ +package core.game.node.entity.skill.farming + +import core.cache.def.impl.NPCDefinition +import core.game.content.dialogue.DialoguePlugin +import core.game.interaction.OptionHandler +import core.game.node.Node +import core.game.node.entity.npc.NPC +import core.game.node.entity.player.Player +import core.game.node.item.Item +import core.plugin.Initializable +import core.plugin.Plugin + +@Initializable +class FarmerPayOptionHandler : OptionHandler() { + override fun newInstance(arg: Any?): Plugin { + NPCDefinition.setOptionHandler("pay",this) + NPCDefinition.setOptionHandler("pay (north)",this) + NPCDefinition.setOptionHandler("pay (south)",this) + NPCDefinition.setOptionHandler("pay (north-west)",this) + NPCDefinition.setOptionHandler("pay (south-east)",this) + return this + } + + override fun handle(player: Player?, node: Node?, option: String?): Boolean { + player ?: return false + node ?: return false + val farmer = Farmers.forId(node.id) + + if(farmer == null){ + player.sendMessage("This shouldn't be happening. Report this.") + return true + } + + val fPatch = when(option){ + "pay" -> farmer.patches[0] + "pay (north)","pay (north-west)" -> farmer.patches[0] + "pay (south)","pay (south-east)" -> farmer.patches[1] + else -> farmer.patches[0] + } + + val patch = fPatch.getPatchFor(player) + if(patch.plantable == null){ + player.dialogueInterpreter.sendDialogue("I have nothing to protect in that patch.") + return true + } + + if(patch.protectionPaid){ + player.dialogueInterpreter.sendDialogue("I have already paid to protect that patch.") + return true + } + + player.dialogueInterpreter.open(FarmerPayDialogue.KEY,node.asNpc(),patch) + return true + } + + @Initializable + class FarmerPayDialogue(player: Player? = null) : DialoguePlugin(player){ + var patch: Patch? = null + var item: Item? = null + + companion object { + @JvmField + val KEY = 1256743 + } + + override fun newInstance(player: Player?): DialoguePlugin { + return FarmerPayDialogue(player) + } + + override fun open(vararg args: Any?): Boolean { + npc = (args[0] as NPC).getShownNPC(player) + patch = (args[1] as Patch) + if(patch == null){ + npc("Hello.") + stage = 1000 + return true + } else { + item = patch?.plantable?.protectionItem + if(item == null) npc("Sorry, I won't protect that.").also { stage = 1000 } + else{ + val name = item?.name?.toLowerCase() + npc("I would like ${item?.amount} $name","to protect that patch.") + stage = 0 + } + } + return true + } + + override fun handle(interfaceId: Int, buttonId: Int): Boolean { + when(stage){ + 0 -> options("Sure!","No, thanks.").also { stage++ } + 1 -> when(buttonId){ + 1 -> player("Sure!").also { stage++ } + 2 -> player("No, thanks.").also { stage = 1000 } + } + 2 -> { + if(player.inventory.containsItem(item)){ + player("Here you go.").also { stage = 10 } + player.inventory.remove() + } else { + item = Item(item!!.noteChange,item!!.amount) + if(player.inventory.containsItem(item)){ + player("Here you go.").also { stage = 10 } + } else { + player("I don't have that to give.").also { stage = 20 } + } + } + } + + 10 -> { + if(player.inventory.remove(item)){ + npc("Thank you! I'll keep an eye on this patch.").also { stage = 1000 } + patch?.protectionPaid = true + } else { + npc("That stuff just... vanished....").also { stage = 1000 } + } + } + + 20 -> { + npc("Come back when you do.") + stage = 1000 + } + + 1000 -> end() + } + return true + } + + override fun getIds(): IntArray { + return intArrayOf(KEY) + } + + } + +} \ No newline at end of file diff --git a/Server/src/main/java/Server/core/game/node/entity/skill/farming/Farmers.kt b/Server/src/main/java/Server/core/game/node/entity/skill/farming/Farmers.kt new file mode 100644 index 000000000..cafb86168 --- /dev/null +++ b/Server/src/main/java/Server/core/game/node/entity/skill/farming/Farmers.kt @@ -0,0 +1,32 @@ +package core.game.node.entity.skill.farming + +enum class Farmers(val id: Int, val patches: Array) { + LYRA(2326, arrayOf(FarmingPatch.PORT_PHAS_ALLOTMENT_NW,FarmingPatch.PORT_PHAS_ALLOTMENT_SE)), + ELSTAN(2323, arrayOf(FarmingPatch.S_FALADOR_ALLOTMENT_NW,FarmingPatch.S_FALADOR_ALLOTMENT_SE)), + HESKEL(2340, arrayOf(FarmingPatch.N_FALADOR_TREE)), + ALAIN(2339, arrayOf(FarmingPatch.TAVERLY_TREE)), + DANTAERA(2324, arrayOf(FarmingPatch.CATHERBY_ALLOTMENT_N,FarmingPatch.CATHERBY_ALLOTMENT_S)), + ELLENA(2331, arrayOf(FarmingPatch.CATHERBY_FRUIT_TREE)), + SELENA(2332, arrayOf(FarmingPatch.YANILLE_HOPS)), + KRAGEN(2325, arrayOf(FarmingPatch.ARDOUGNE_ALLOTMENT_N,FarmingPatch.ARDOUGNE_ALLOTMENT_S)), + BOLONGO(2343, arrayOf(FarmingPatch.GNOME_STRONGHOLD_FRUIT_TREE)), + PRISSY_SCILLA(1037, arrayOf(FarmingPatch.GNOME_STRONGHOLD_TREE)), + FAYETH(2342, arrayOf(FarmingPatch.LUMBRIDGE_TREE)), + TREZNOR(2341, arrayOf(FarmingPatch.VARROCK_TREE)), + VASQUEN(2333, arrayOf(FarmingPatch.LUMBRIDGE_HOPS)), + RHONEN(2334, arrayOf(FarmingPatch.MCGRUBOR_HOPS)), + FRANCIS(2327, arrayOf(FarmingPatch.ENTRANA_HOPS)), + DREVEN(2335, arrayOf(FarmingPatch.CHAMPIONS_GUILD_BUSH)), + TARIA(2336, arrayOf(FarmingPatch.RIMMINGTON_BUSH)), + TORRELL(2338, arrayOf(FarmingPatch.ARDOUGNE_BUSH)); + + companion object{ + @JvmField + val farmers = values().map { it.id to it }.toMap() + + @JvmStatic + fun forId(id: Int): Farmers?{ + return farmers[id] + } + } +} \ No newline at end of file diff --git a/Server/src/main/java/Server/core/game/node/entity/skill/farming/Patch.kt b/Server/src/main/java/Server/core/game/node/entity/skill/farming/Patch.kt index 9d4455113..afb3d6c2d 100644 --- a/Server/src/main/java/Server/core/game/node/entity/skill/farming/Patch.kt +++ b/Server/src/main/java/Server/core/game/node/entity/skill/farming/Patch.kt @@ -10,6 +10,7 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl var diseaseMod = 0 var compost = CompostType.NONE + var protectionPaid = false fun setNewHarvestAmount() { if(patch.type == PatchType.ALLOTMENT){ @@ -126,7 +127,7 @@ class Patch(val player: Player, val patch: FarmingPatch, var plantable: Plantabl CompostType.SUPER -> 13 } - if(RandomFunction.random(128) <= (17 - diseaseMod) && !isWatered && !isGrown()){ + if(RandomFunction.random(128) <= (17 - diseaseMod) && !isWatered && !isGrown() && !protectionPaid){ //bush, tree, fruit tree can not disease on stage 1(0) of growth. if(!((patch.type == PatchType.BUSH || patch.type == PatchType.TREE || patch.type == PatchType.FRUIT_TREE) && currentGrowthStage == 0)) { isDiseased = true diff --git a/Server/src/main/java/Server/core/game/node/entity/state/newsys/states/FarmingState.kt b/Server/src/main/java/Server/core/game/node/entity/state/newsys/states/FarmingState.kt index a92207777..269bda4a9 100644 --- a/Server/src/main/java/Server/core/game/node/entity/state/newsys/states/FarmingState.kt +++ b/Server/src/main/java/Server/core/game/node/entity/state/newsys/states/FarmingState.kt @@ -50,6 +50,7 @@ class FarmingState(player: Player? = null) : State(player) { p.put("patch-harvestAmt",patch.harvestAmt) p.put("patch-checkHealth",patch.isCheckHealth) p.put("patch-compost",patch.compost.ordinal) + p.put("patch-paidprot",patch.protectionPaid) patches.add(p) } val bins = JSONArray() @@ -93,11 +94,13 @@ class FarmingState(player: Player? = null) : State(player) { val checkHealth = p["patch-checkHealth"] as Boolean val savedState = p["patch-state"].toString().toInt() val compostOrdinal = p["patch-compost"].toString().toInt() + val protectionPaid = p["patch-paidprot"] as Boolean val fPatch = FarmingPatch.values()[patchOrdinal] val plantable = if(patchPlantableOrdinal != -1) Plantable.values()[patchPlantableOrdinal] else null val patch = Patch(player,fPatch,plantable,patchStage,patchDiseased,patchDead,patchWatered,nextGrowth,harvestAmt,checkHealth) patch.compost = CompostType.values()[compostOrdinal] + patch.protectionPaid = protectionPaid if(patch.currentGrowthStage < patch.plantable?.stages ?: 0 && !patch.isWeedy()){ val startTime = (patch.nextGrowth - TimeUnit.MINUTES.toMillis(patch.patch.type.stageGrowthTime * (patch.currentGrowthStage + 1).toLong())) var expectedStage = Math.floor((System.currentTimeMillis() - startTime.toDouble()) / TimeUnit.MINUTES.toMillis(patch.patch.type.stageGrowthTime.toLong())).toInt()