Fixed inconsistent and inauthentic messages for fishing

Fixed item grinding consuming the whole stack sometimes
Fixed incorrect Fremennik diary cheese task
Fixed Seer's diary candle task
This commit is contained in:
Bonesy 2024-01-29 09:31:30 +00:00 committed by Ryan
parent a7b5e77318
commit 020d5a9c05
13 changed files with 254 additions and 164 deletions

View file

@ -1,5 +1,8 @@
package content.global.skill.cooking.dairy; package content.global.skill.cooking.dairy;
import content.region.fremennik.rellekka.handlers.RellekkaUtils;
import content.region.fremennik.rellekka.handlers.RellekkaZone;
import core.game.event.ResourceProducedEvent;
import core.game.node.entity.player.Player; import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.diary.DiaryType; import core.game.node.entity.player.link.diary.DiaryType;
import core.game.node.entity.skill.SkillPulse; import core.game.node.entity.skill.SkillPulse;
@ -11,6 +14,9 @@ import core.game.world.update.flag.context.Animation;
import core.tools.StringUtils; import core.tools.StringUtils;
import org.rs09.consts.Items; import org.rs09.consts.Items;
import static core.api.ContentAPIKt.location;
import static core.api.ContentAPIKt.sendMessage;
/** /**
* Represents the skill pulse used to make a dairy product. * Represents the skill pulse used to make a dairy product.
* @author 'Vexia * @author 'Vexia
@ -106,13 +112,8 @@ public final class DairyChurnPulse extends SkillPulse<Item> {
} }
} }
player.getPacketDispatch().sendMessage("You make " + (StringUtils.isPlusN(dairy.getProduct().getName().toLowerCase()) ? "an" : "a") + " " + dairy.getProduct().getName().toLowerCase() + "."); player.getPacketDispatch().sendMessage("You make " + (StringUtils.isPlusN(dairy.getProduct().getName().toLowerCase()) ? "an" : "a") + " " + dairy.getProduct().getName().toLowerCase() + ".");
player.dispatch(new ResourceProducedEvent(dairy.getProduct().getId(), amount, node, BUCKET_OF_MILK.getId()));
player.getSkills().addExperience(Skills.COOKING, dairy.getExperience(), true); player.getSkills().addExperience(Skills.COOKING, dairy.getExperience(), true);
// Seers village diary
if (player.getLocation().withinDistance(new Location(2730, 3578, 0))
&& !player.getAchievementDiaryManager().getDiary(DiaryType.SEERS_VILLAGE).isComplete(0,8)) {
player.getAchievementDiaryManager().getDiary(DiaryType.SEERS_VILLAGE).updateTask(player,0,8,true);
}
break; break;
} }
} }

View file

@ -9,9 +9,9 @@ import content.global.skill.skillcapeperks.SkillcapePerks.Companion.isActive
import content.global.skill.summoning.familiar.Forager import content.global.skill.summoning.familiar.Forager
import core.api.* import core.api.*
import core.game.event.ResourceProducedEvent import core.game.event.ResourceProducedEvent
import core.game.interaction.Clocks
import core.game.interaction.IntType import core.game.interaction.IntType
import core.game.interaction.InteractionListener import core.game.interaction.InteractionListener
import core.game.interaction.Clocks
import core.game.node.Node import core.game.node.Node
import core.game.node.entity.npc.NPC import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player import core.game.node.entity.player.Player
@ -42,6 +42,7 @@ class FishingListener : InteractionListener{
val npc = node as? NPC ?: return clearScripts(player) val npc = node as? NPC ?: return clearScripts(player)
val spot = FishingSpot.forId(npc.id) ?: return clearScripts(player) val spot = FishingSpot.forId(npc.id) ?: return clearScripts(player)
val op = spot.getOptionByName(getUsedOption(player)) ?: return clearScripts(player) val op = spot.getOptionByName(getUsedOption(player)) ?: return clearScripts(player)
var forager: Forager? = null var forager: Forager? = null
if (player.familiarManager.hasFamiliar() && player.familiarManager.familiar is Forager) { if (player.familiarManager.hasFamiliar() && player.familiarManager.familiar is Forager) {
@ -58,8 +59,21 @@ class FishingListener : InteractionListener{
val dest = player.location.transform(player.direction) val dest = player.location.transform(player.direction)
Pathfinder.find(it, dest).walk(it) Pathfinder.find(it, dest).walk(it)
} }
when (op.option) {
"cage" -> if (spot.name == "CAGE_HARPOON") {
sendMessage(player, "You attempt to catch a lobster.")
} else sendMessage(player, "You attempt to catch a crayfish.")
"harpoon" -> sendMessage(player, "You start harpooning fish.")
"net" -> sendMessage(player, "You cast out your net...")
in arrayOf("bait", "lure") -> {
sendMessage(player, "You cast out your line...")
sendMessage(player, "You attempt to catch a fish.")
}
else -> { // Probably not authentic, but covers unknown cases.
sendMessage(player, "You attempt to catch some fish...") sendMessage(player, "You attempt to catch some fish...")
} }
}
}
if (clockReady(player, Clocks.SKILLING)) { if (clockReady(player, Clocks.SKILLING)) {
anim(player, op) anim(player, op)
@ -72,11 +86,15 @@ class FishingListener : InteractionListener{
val bigFishId = Fish.getBigFish(fish) val bigFishId = Fish.getBigFish(fish)
val bigFishChance = if (GameWorld.settings?.isDevMode == true) 10 else 5000 val bigFishChance = if (GameWorld.settings?.isDevMode == true) 10 else 5000
if (bigFishId != null && RandomFunction.roll(bigFishChance)) { if (bigFishId != null && RandomFunction.roll(bigFishChance)) {
sendMessage(player, "You catch an enormous" + getItemName(fish!!.id).lowercase().replace("raw", "") + "!") sendMessage(player, "You catch an enormous" + getItemName(fish.id).lowercase().replace("raw", "") + "!")
addItemOrDrop(player, bigFishId, 1) addItemOrDrop(player, bigFishId, 1)
} else { } else {
var msg = if (fish == Fish.ANCHOVIE || fish == Fish.SHRIMP) "You catch some" else "You catch a" var msg = when (fish) {
msg += getItemName(fish!!.id).lowercase().replace("raw", "").replace("big", "") in arrayOf(Fish.ANCHOVIE, Fish.SHRIMP, Fish.SEAWEED) -> "You catch some "
in arrayOf(Fish.OYSTER) -> "You catch an "
else -> "You catch a "
}
msg += getItemName(fish.id).lowercase().replace("raw ", "").replace("big ", "")
msg += if (fish == Fish.SHARK) "!" else "." msg += if (fish == Fish.SHARK) "!" else "."
sendMessage(player, msg) sendMessage(player, msg)
addItemOrDrop(player, item.id, item.amount) addItemOrDrop(player, item.id, item.amount)
@ -109,20 +127,29 @@ class FishingListener : InteractionListener{
private fun checkRequirements(player: Player, option: FishingOption, node: Node) : Boolean { private fun checkRequirements(player: Player, option: FishingOption, node: Node) : Boolean {
if (!inInventory(player, option.tool) && !hasBarbTail(player, option)) { if (!inInventory(player, option.tool) && !hasBarbTail(player, option)) {
player.dialogueInterpreter.sendDialogue("You need a " + getItemName(option.tool).lowercase() + " to catch these fish.") // The fly fishing rod & net dialogue is confirmed from videos. Others are assumptions based upon this.
var msg = "You need a "
msg += if (getItemName(option.tool).contains("net", true)) "net to " else "${getItemName(option.tool).lowercase()} to "
msg += if (option.option in arrayOf("lure", "bait")) "${option.option} these fish." else "catch these fish."
sendDialogue(player, msg)
return false return false
} }
if (!option.hasBait(player)) { if (!option.hasBait(player)) {
player.dialogueInterpreter.sendDialogue("You don't have any " + option.getBaitName().lowercase() + "s left.") var msg = "You don't have any " + option.getBaitName().lowercase()
msg += if (option.getBaitName() == getItemName(Items.FISHING_BAIT_313)) " left." else "s left."
sendDialogue(player, msg)
return false return false
} }
if (player.skills.getLevel(Skills.FISHING) < option!!.level) { if (!hasLevelDyn(player, Skills.FISHING, option.level)) {
val f = option!!.fish[option!!.fish.size - 1] sendDialogue(player, "You need a Fishing level of at least ${option.level} to ${option.option} these fish.")
player.dialogueInterpreter.sendDialogue("You need a fishing level of " + f.level + " to catch " + (if (f == Fish.SHRIMP || f == Fish.ANCHOVIE) "" else "a") + " " + getItemName(f.id).lowercase() + ".".trim { it <= ' ' })
return false return false
} }
if (player.inventory.freeSlots() == 0) { if (freeSlots(player) == 0) {
player.dialogueInterpreter.sendDialogue("You don't have enough space in your inventory.") if (option.fish.contains(Fish.LOBSTER)) {
sendDialogue(player, "You can't carry any more lobsters.")
} else {
sendDialogue(player, "You can't carry any more fish.")
}
return false return false
} }
return node.isActive && node.location.withinDistance(player.location, 1) return node.isActive && node.location.withinDistance(player.location, 1)

View file

@ -1,31 +1,29 @@
package content.global.skill.gather.fishing package content.global.skill.gather.fishing
import core.game.event.ResourceProducedEvent
import content.data.skill.SkillingPets import content.data.skill.SkillingPets
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.game.node.entity.player.link.skillertasks.SkillTasks
import core.game.node.entity.skill.SkillPulse
import core.game.node.entity.skill.Skills
import content.global.skill.fishing.Fish import content.global.skill.fishing.Fish
import content.global.skill.fishing.FishingOption import content.global.skill.fishing.FishingOption
import content.global.skill.skillcapeperks.SkillcapePerks import content.global.skill.skillcapeperks.SkillcapePerks
import content.global.skill.skillcapeperks.SkillcapePerks.Companion.isActive import content.global.skill.skillcapeperks.SkillcapePerks.Companion.isActive
import content.global.skill.summoning.familiar.Forager import content.global.skill.summoning.familiar.Forager
import core.api.addItem import core.api.*
import core.api.getItemName import core.game.event.ResourceProducedEvent
import core.api.inEquipment import core.game.node.entity.npc.NPC
import core.api.inInventory import core.game.node.entity.player.Player
import core.game.node.entity.player.link.skillertasks.SkillTasks
import core.game.node.entity.skill.SkillPulse
import core.game.node.entity.skill.Skills
import core.game.node.item.Item import core.game.node.item.Item
import core.game.system.command.sets.STATS_BASE
import core.game.system.command.sets.STATS_FISH
import core.game.system.task.Pulse import core.game.system.task.Pulse
import core.game.world.GameWorld.Pulser
import core.game.world.map.Location import core.game.world.map.Location
import core.game.world.map.path.Pathfinder import core.game.world.map.path.Pathfinder
import core.game.world.update.flag.context.Animation import core.game.world.update.flag.context.Animation
import core.tools.RandomFunction import core.tools.RandomFunction
import core.game.system.command.sets.STATS_BASE
import core.game.system.command.sets.STATS_FISH
import core.game.world.GameWorld.Pulser
import core.tools.colorize import core.tools.colorize
import org.rs09.consts.Items
/** /**
* Handles a fishing pulse. * Handles a fishing pulse.
@ -58,24 +56,32 @@ class FishingPulse(player: Player?, npc: NPC, private val option: FishingOption?
} }
player.debug(inInventory(player, option.tool).toString()) player.debug(inInventory(player, option.tool).toString())
if (!inInventory(player, option.tool) && !hasBarbTail()) { if (!inInventory(player, option.tool) && !hasBarbTail()) {
// The fly fishing rod & net dialogue is confirmed from videos. Others are assumptions based upon this.
player.dialogueInterpreter.sendDialogue("You need a " + getItemName(option.tool).lowercase() + " to catch these fish.") var msg = "You need a "
msg += if (getItemName(option.tool).contains("net", true)) "net to " else "${getItemName(option.tool).lowercase()} to "
msg += if (option.option in arrayOf("lure", "bait")) "${option.option} these fish." else "catch these fish."
sendDialogue(player, msg)
stop() stop()
return false return false
} }
if (!option.hasBait(player)) { if (!option.hasBait(player)) {
player.dialogueInterpreter.sendDialogue("You don't have any " + option.getBaitName().lowercase() + "s left.") var msg = "You don't have any " + option.getBaitName().lowercase()
msg += if (option.getBaitName() == getItemName(Items.FISHING_BAIT_313)) " left." else "s left."
sendDialogue(player, msg)
stop() stop()
return false return false
} }
if (player.skills.getLevel(Skills.FISHING) < option!!.level) { if (!hasLevelDyn(player, Skills.FISHING, option.level)) {
val f = option!!.fish[option!!.fish.size - 1] sendDialogue(player, "You need a Fishing level of at least ${option.level} to ${option.option} these fish.")
player.dialogueInterpreter.sendDialogue("You need a fishing level of " + f.level + " to catch " + (if (f == Fish.SHRIMP || f == Fish.ANCHOVIE) "" else "a") + " " + getItemName(f.id).lowercase() + ".".trim { it <= ' ' })
stop() stop()
return false return false
} }
if (player.inventory.freeSlots() == 0) { if (freeSlots(player) == 0) {
player.dialogueInterpreter.sendDialogue("You don't have enough space in your inventory.") if (option.fish.contains(Fish.LOBSTER)) {
sendDialogue(player, "You can't carry any more lobsters.")
} else {
sendDialogue(player, "You can't carry any more fish.")
}
stop() stop()
return false return false
} }
@ -240,15 +246,23 @@ class FishingPulse(player: Player?, npc: NPC, private val option: FishingOption?
override fun message(type: Int) { override fun message(type: Int) {
when (type) { when (type) {
0 -> player.packetDispatch.sendMessage(option!!.getStartMessage()) 0 -> sendMessage(player, option!!.getStartMessage())
2 -> { 2 -> {
player.packetDispatch.sendMessage( var msg = when (fish) {
if (fish == Fish.ANCHOVIE || fish == Fish.SHRIMP) "You catch some " + getItemName(fish!!.id).lowercase() in arrayOf(Fish.ANCHOVIE, Fish.SHRIMP, Fish.SEAWEED) -> "You catch some "
.replace("raw", "") in arrayOf(Fish.OYSTER) -> "You catch an "
.trim { it <= ' ' } + "." else "You catch a " + getItemName(fish!!.id).lowercase() else -> "You catch a "
.replace("raw", "").trim { it <= ' ' } + ".") }
msg += getItemName(fish!!.id).lowercase().replace("raw ", "").replace("big ", "")
msg += if (fish == Fish.SHARK) "!" else "."
sendMessage(player, msg)
if (player.inventory.freeSlots() == 0) { if (player.inventory.freeSlots() == 0) {
player.dialogueInterpreter.sendDialogue("You don't have enough space in your inventory.") if (fish == Fish.LOBSTER) {
sendDialogue(player, "You can't carry any more lobsters.")
} else {
sendDialogue(player, "You can't carry any more fish.")
}
stop() stop()
} }
} }

View file

@ -1,9 +1,12 @@
package content.global.skill.herblore package content.global.skill.herblore
import core.api.addItem
import core.api.amountInInventory
import core.api.removeItem
import core.game.dialogue.SkillDialogueHandler
import core.game.interaction.NodeUsageEvent import core.game.interaction.NodeUsageEvent
import core.game.interaction.UseWithHandler import core.game.interaction.UseWithHandler
import core.game.node.entity.skill.SkillPulse import core.game.node.entity.skill.SkillPulse
import content.global.skill.herblore.GrindingItem
import core.game.node.item.Item import core.game.node.item.Item
import core.game.world.update.flag.context.Animation import core.game.world.update.flag.context.Animation
import core.net.packet.PacketRepository import core.net.packet.PacketRepository
@ -11,7 +14,9 @@ import core.net.packet.context.ChildPositionContext
import core.net.packet.out.RepositionChild import core.net.packet.out.RepositionChild
import core.plugin.Initializable import core.plugin.Initializable
import core.plugin.Plugin import core.plugin.Plugin
import core.game.dialogue.SkillDialogueHandler import org.rs09.consts.Items
import kotlin.math.ceil
import kotlin.math.roundToInt
/** /**
* plugin used to handle the grinding of an item. * plugin used to handle the grinding of an item.
@ -36,8 +41,13 @@ class GrindItemPlugin : UseWithHandler(233) {
var amt = 0 var amt = 0
init { init {
amt = amount amt = amount
if(amt > player.inventory.getAmount(node)){ if(amt > amountInInventory(player, node.id)) {
amt = player.inventory.getAmount(node) amt = amountInInventory(player, node.id)
}
if (node.id == FISHING_BAIT) {
if(amt > (amountInInventory(player, node.id) / 10)) {
amt = ceil(amountInInventory(player, node.id).toDouble() / 10).roundToInt()
}
} }
super.setDelay(2) super.setDelay(2)
} }
@ -50,8 +60,20 @@ class GrindItemPlugin : UseWithHandler(233) {
} }
override fun reward(): Boolean { override fun reward(): Boolean {
if(player.inventory.remove(node)){ if (node.id == Items.FISHING_BAIT_313) {
player.inventory.add(GrindingItem.forItem(node).product) var quantity = 0
quantity = if (amountInInventory(player, FISHING_BAIT) >= 10) {
10
} else {
amountInInventory(player, FISHING_BAIT)
}
if (removeItem(player, Item(node.id, quantity))) {
addItem(player, GrindingItem.forItem(node).product.id, quantity)
}
} else {
if (removeItem(player, Item(node.id, 1))) {
addItem(player, GrindingItem.forItem(node).product.id)
}
} }
amt-- amt--
return amt <= 0 return amt <= 0
@ -61,7 +83,7 @@ class GrindItemPlugin : UseWithHandler(233) {
} }
override fun getAll(index: Int): Int { override fun getAll(index: Int): Int {
return player.inventory.getAmount(event.usedItem) return amountInInventory(player, event.usedItem.id)
} }
} }
handler.open() handler.open()
@ -74,5 +96,6 @@ class GrindItemPlugin : UseWithHandler(233) {
* Represents the animation to use. * Represents the animation to use.
*/ */
private val ANIMATION = Animation(364) private val ANIMATION = Animation(364)
private const val FISHING_BAIT = Items.FISHING_BAIT_313
} }
} }

View file

@ -8,21 +8,21 @@ import core.game.node.item.Item;
* @author Vexia * @author Vexia
*/ */
public enum GrindingItem { public enum GrindingItem {
UNICORN_HORN(new Item[] { new Item(237) },new Item(235)), UNICORN_HORN(new Item[] { new Item(Items.UNICORN_HORN_237) }, new Item(Items.UNICORN_HORN_DUST_235)),
KEBBIT_TEETH(new Item[] { new Item(10109) }, new Item(10111)), KEBBIT_TEETH(new Item[] { new Item(Items.KEBBIT_TEETH_10109) }, new Item(Items.KEBBIT_TEETH_DUST_10111)),
BIRDS_NEST(new Item[] { new Item(5070), new Item(5071), new Item(5072), new Item(5073), new Item(5074), new Item(5075) }, new Item(6693)), BIRDS_NEST(new Item[] { new Item(Items.BIRDS_NEST_5075) }, new Item(Items.CRUSHED_NEST_6693)),
GOAT_HORN(new Item[] { new Item(9735) }, new Item(9736)), GOAT_HORN(new Item[] { new Item(Items.DESERT_GOAT_HORN_9735) }, new Item(Items.GOAT_HORN_DUST_9736)),
MUD_RUNE(new Item[] { new Item(4698) }, new Item(9594)), MUD_RUNE(new Item[] { new Item(Items.MUD_RUNE_4698) }, new Item(Items.GROUND_MUD_RUNES_9594)),
ASHES(new Item[] { new Item(592) }, new Item(8865)), ASHES(new Item[] { new Item(Items.ASHES_592) }, new Item(Items.GROUND_ASHES_8865)),
POISON_KARAMBWAN(new Item[] { new Item(3146) }, new Item(3152)), POISON_KARAMBWAN(new Item[] { new Item(Items.POISON_KARAMBWAN_3146) }, new Item(Items.KARAMBWAN_PASTE_3152)),
FISHING_BAIT(new Item[] { new Item(313) }, new Item(12129)), FISHING_BAIT(new Item[] { new Item(Items.FISHING_BAIT_313) }, new Item(Items.GROUND_FISHING_BAIT_12129)),
SEAWEED(new Item[] { new Item(401) }, new Item(6683)), SEAWEED(new Item[] { new Item(Items.SEAWEED_401) }, new Item(Items.GROUND_SEAWEED_6683)),
BAT_BONES(new Item[] { new Item(530) }, new Item(2391)), BAT_BONES(new Item[] { new Item(Items.BAT_BONES_530) }, new Item(Items.GROUND_BAT_BONES_2391)),
CHARCOAL(new Item[] { new Item(973) }, new Item(704)), CHARCOAL(new Item[] { new Item(Items.CHARCOAL_973) }, new Item(Items.GROUND_CHARCOAL_704)),
ASTRAL_RUNE_SHARDS(new Item[] { new Item(11156) }, new Item(11155)), ASTRAL_RUNE_SHARDS(new Item[] { new Item(Items.ASTRAL_RUNE_SHARDS_11156) }, new Item(Items.GROUND_ASTRAL_RUNE_11155)),
GARLIC(new Item[] { new Item(1550) }, new Item(4668)), GARLIC(new Item[] { new Item(Items.GARLIC_1550) }, new Item(Items.GARLIC_POWDER_4668)),
DRAGON_SCALE(new Item[] { new Item(243) }, new Item(241)), DRAGON_SCALE(new Item[] { new Item(Items.BLUE_DRAGON_SCALE_243) }, new Item(Items.DRAGON_SCALE_DUST_241)),
ANCHOVIES(new Item[] { new Item(319) }, new Item(11266)), ANCHOVIES(new Item[] { new Item(Items.ANCHOVIES_319) }, new Item(Items.ANCHOVY_PASTE_11266)),
CHOCOLATE_BAR(new Item[] {new Item(Items.CHOCOLATE_BAR_1973)}, new Item(Items.CHOCOLATE_DUST_1975)), CHOCOLATE_BAR(new Item[] {new Item(Items.CHOCOLATE_BAR_1973)}, new Item(Items.CHOCOLATE_DUST_1975)),
GUAM_LEAF(new Item[] { new Item(Items.CLEAN_GUAM_249) }, new Item(Items.GROUND_GUAM_6681)); GUAM_LEAF(new Item[] { new Item(Items.CLEAN_GUAM_249) }, new Item(Items.GROUND_GUAM_6681));

View file

@ -1,5 +1,6 @@
package content.global.skill.thieving; package content.global.skill.thieving;
import core.game.event.ResourceProducedEvent;
import core.game.node.entity.skill.SkillPulse; import core.game.node.entity.skill.SkillPulse;
import core.game.node.entity.skill.Skills; import core.game.node.entity.skill.Skills;
import core.game.node.entity.npc.NPC; import core.game.node.entity.npc.NPC;
@ -119,6 +120,7 @@ public final class StallThiefPulse extends SkillPulse<Scenery> {
return true; return true;
} }
player.getPacketDispatch().sendMessage("You steal " + (StringUtils.isPlusN(item.getName()) ? "an" : "a") + " " + item.getName().toLowerCase() + " from the " + stall.name().toLowerCase().replace('_',' ') + "."); player.getPacketDispatch().sendMessage("You steal " + (StringUtils.isPlusN(item.getName()) ? "an" : "a") + " " + item.getName().toLowerCase() + " from the " + stall.name().toLowerCase().replace('_',' ') + ".");
player.dispatch(new ResourceProducedEvent(item.getId(), item.getAmount(), node, 0));
} }
return true; return true;
} }

View file

@ -1,16 +1,9 @@
package content.region.fremennik.diary package content.region.fremennik.diary
import core.game.node.entity.player.Player
import core.game.node.entity.player.link.diary.DiaryType
import core.game.world.map.zone.ZoneBorders
import org.rs09.consts.Items
import org.rs09.consts.NPCs
import org.rs09.consts.Scenery
import content.minigame.barbassault.CaptainCainDialogue
import content.region.fremennik.rellekka.dialogue.HuntingExpertRellekkaDialogue
import content.global.handlers.iface.FairyRing import content.global.handlers.iface.FairyRing
import content.global.skill.cooking.dairy.DairyChurnDialogue import content.minigame.barbassault.CaptainCainDialogue
import content.region.fremennik.jatizso.dialogue.TowerGuardDialogue import content.region.fremennik.jatizso.dialogue.TowerGuardDialogue
import content.region.fremennik.rellekka.dialogue.HuntingExpertRellekkaDialogue
import content.region.fremennik.rellekka.quest.thefremenniktrials.ChieftanBrundt import content.region.fremennik.rellekka.quest.thefremenniktrials.ChieftanBrundt
import core.api.inBorders import core.api.inBorders
import core.api.inEquipment import core.api.inEquipment
@ -18,9 +11,12 @@ import core.game.diary.AreaDiaryTask
import core.game.diary.DiaryEventHookBase import core.game.diary.DiaryEventHookBase
import core.game.diary.DiaryLevel import core.game.diary.DiaryLevel
import core.game.event.* import core.game.event.*
import core.game.node.entity.player.Player
import core.game.node.entity.player.link.SpellBookManager import core.game.node.entity.player.link.SpellBookManager
import core.game.node.entity.player.link.diary.DiaryType
import core.game.node.entity.skill.Skills import core.game.node.entity.skill.Skills
import org.rs09.consts.Components import core.game.world.map.zone.ZoneBorders
import org.rs09.consts.*
class FremennikAchievementDiary : DiaryEventHookBase(DiaryType.FREMENNIK) { class FremennikAchievementDiary : DiaryEventHookBase(DiaryType.FREMENNIK) {
companion object { companion object {
@ -166,16 +162,6 @@ class FremennikAchievementDiary : DiaryEventHookBase(DiaryType.FREMENNIK) {
) )
} }
} }
is DairyChurnDialogue -> {
if (event.optionId == 12) {
finishTask(
player,
DiaryLevel.MEDIUM,
MediumTasks.MAKE_CHEESE_WITH_CHURN
)
}
}
} }
} }
@ -187,6 +173,18 @@ class FremennikAchievementDiary : DiaryEventHookBase(DiaryType.FREMENNIK) {
DiaryLevel.EASY, DiaryLevel.EASY,
EasyTasks.PIER_CATCH_FISH EasyTasks.PIER_CATCH_FISH
) )
} else if (event.itemId == Items.CHEESE_1985) {
finishTask(
player,
DiaryLevel.MEDIUM,
MediumTasks.MAKE_CHEESE_WITH_CHURN
)
} else if (event.source.id == Scenery.FISH_STALL_4277) {
finishTask(
player,
DiaryLevel.MEDIUM,
MediumTasks.STEAL_FISH_FROM_STALL
)
} }
/* After Royal trouble quest /* After Royal trouble quest
@ -298,14 +296,6 @@ class FremennikAchievementDiary : DiaryEventHookBase(DiaryType.FREMENNIK) {
override fun onInteracted(player: Player, event: InteractionEvent) { override fun onInteracted(player: Player, event: InteractionEvent) {
when (player.viewport.region.id) { when (player.viewport.region.id) {
10553 -> if (event.target.id == Scenery.FISH_STALL_4277 && event.option == "steal-from" && player.questRepository.isComplete("Fremennik Trials")) {
finishTask(
player,
DiaryLevel.MEDIUM,
MediumTasks.STEAL_FISH_FROM_STALL
)
}
10811 -> if (event.target.id == Scenery.COLLAPSED_TRAP_19233 && inBorders(player, RELLEKKA_HUNTING_AREA) && event.option == "dismantle") { 10811 -> if (event.target.id == Scenery.COLLAPSED_TRAP_19233 && inBorders(player, RELLEKKA_HUNTING_AREA) && event.option == "dismantle") {
finishTask( finishTask(
player, player,

View file

@ -1,12 +1,5 @@
package content.region.kandarin.seers.diary package content.region.kandarin.seers.diary
import core.game.node.entity.player.Player
import core.game.node.entity.player.link.diary.DiaryType
import core.game.node.item.Item
import core.game.world.map.Location
import core.game.world.map.zone.ZoneBorders
import org.rs09.consts.Items
import org.rs09.consts.NPCs
import content.global.handlers.iface.FairyRing import content.global.handlers.iface.FairyRing
import content.global.handlers.item.withnpc.PoisonChaliceOnKingArthurDialogue import content.global.handlers.item.withnpc.PoisonChaliceOnKingArthurDialogue
import core.api.inBorders import core.api.inBorders
@ -14,8 +7,15 @@ import core.api.inEquipment
import core.game.diary.DiaryEventHookBase import core.game.diary.DiaryEventHookBase
import core.game.diary.DiaryLevel import core.game.diary.DiaryLevel
import core.game.event.* import core.game.event.*
import core.game.node.entity.player.Player
import core.game.node.entity.player.link.diary.DiaryType
import core.game.node.item.Item
import core.game.world.map.Location
import core.game.world.map.zone.ZoneBorders
import org.rs09.consts.Items
import org.rs09.consts.NPCs
class SeersVillageAchivementDiary : DiaryEventHookBase(DiaryType.SEERS_VILLAGE) { class SeersVillageAchievementDiary : DiaryEventHookBase(DiaryType.SEERS_VILLAGE) {
companion object { companion object {
private const val ATTRIBUTE_CUT_YEW_COUNT = "diary:seers:cut-yew" private const val ATTRIBUTE_CUT_YEW_COUNT = "diary:seers:cut-yew"
private const val ATTRIBUTE_BASS_CAUGHT = "diary:seers:bass-caught" private const val ATTRIBUTE_BASS_CAUGHT = "diary:seers:bass-caught"
@ -47,6 +47,10 @@ class SeersVillageAchivementDiary : DiaryEventHookBase(DiaryType.SEERS_VILLAGE)
NPCs.AIR_ELEMENTAL_1021, NPCs.WATER_ELEMENTAL_1022 NPCs.AIR_ELEMENTAL_1021, NPCs.WATER_ELEMENTAL_1022
) )
private val CHURN_PRODUCT = arrayOf(
Items.CHEESE_1985, Items.POT_OF_CREAM_2130, Items.PAT_OF_BUTTER_6697
)
object EasyTasks { object EasyTasks {
const val PICK_5_FLAX = 0 const val PICK_5_FLAX = 0
const val WALK_CLOCKWISE_AROUND_MYSTERIOUS_STATUE = 1 const val WALK_CLOCKWISE_AROUND_MYSTERIOUS_STATUE = 1
@ -94,6 +98,14 @@ class SeersVillageAchivementDiary : DiaryEventHookBase(DiaryType.SEERS_VILLAGE)
override fun onResourceProduced(player: Player, event: ResourceProducedEvent) { override fun onResourceProduced(player: Player, event: ResourceProducedEvent) {
when (player.viewport.region.id) { when (player.viewport.region.id) {
10807 -> if (event.itemId in CHURN_PRODUCT) {
finishTask(
player,
DiaryLevel.EASY,
EasyTasks.SINCLAIR_MANSION_USE_CHURN
)
}
10806 -> if (event.itemId == Items.YEW_LOGS_1515) { 10806 -> if (event.itemId == Items.YEW_LOGS_1515) {
progressIncrementalTask( progressIncrementalTask(
player, player,
@ -280,4 +292,14 @@ class SeersVillageAchivementDiary : DiaryEventHookBase(DiaryType.SEERS_VILLAGE)
) )
} }
} }
override fun onItemPurchasedFromShop(player: Player, event: ItemShopPurchaseEvent) {
if (event.itemId == Items.CANDLE_36 && player.viewport.region.id == 11061) {
finishTask(
player,
DiaryLevel.EASY,
EasyTasks.BUY_CANDLE
)
}
}
} }

View file

@ -58,7 +58,7 @@ public final class CandleMakerDialogue extends DialoguePlugin {
NPC npc = node.asNpc(); NPC npc = node.asNpc();
Quest quest = player.getQuestRepository().getQuest("Merlin's Crystal"); Quest quest = player.getQuestRepository().getQuest("Merlin's Crystal");
if (quest.getStage(player) > 60) { if (quest.getStage(player) > 60) {
Shops.openId(player, 198); Shops.openId(player, 56);
} else { } else {
npc.openShop(player); npc.openShop(player);
} }
@ -175,7 +175,7 @@ public final class CandleMakerDialogue extends DialoguePlugin {
case 30: case 30:
end(); end();
if (quest.getStage(player) > 60) { if (quest.getStage(player) > 60) {
Shops.openId(player, 198); Shops.openId(player, 56);
} else { } else {
npc.openShop(player); npc.openShop(player);
} }

View file

@ -1,4 +1,4 @@
package content.region.kandarin.catherby.dialogue; package content.region.misthalin.lumbridge.dialogue;
import core.game.dialogue.DialoguePlugin; import core.game.dialogue.DialoguePlugin;
import core.game.dialogue.FacialExpression; import core.game.dialogue.FacialExpression;
@ -13,7 +13,7 @@ import core.game.node.item.Item;
* @version 1.0 * @version 1.0
*/ */
@Initializable @Initializable
public final class CandleSellerPlugin extends DialoguePlugin { public final class CandleSellerDialogue extends DialoguePlugin {
/** /**
* Represents the coins item. * Represents the coins item.
@ -28,7 +28,7 @@ public final class CandleSellerPlugin extends DialoguePlugin {
/** /**
* Constructs a new {@code CandleSellerPlugin} {@code Object}. * Constructs a new {@code CandleSellerPlugin} {@code Object}.
*/ */
public CandleSellerPlugin() { public CandleSellerDialogue() {
/** /**
* empty. * empty.
*/ */
@ -38,13 +38,13 @@ public final class CandleSellerPlugin extends DialoguePlugin {
* Constructs a new {@code CandleSellerPlugin} {@code Object}. * Constructs a new {@code CandleSellerPlugin} {@code Object}.
* @param player the player. * @param player the player.
*/ */
public CandleSellerPlugin(Player player) { public CandleSellerDialogue(Player player) {
super(player); super(player);
} }
@Override @Override
public DialoguePlugin newInstance(Player player) { public DialoguePlugin newInstance(Player player) {
return new CandleSellerPlugin(player); return new CandleSellerDialogue(player);
} }
@Override @Override

View file

@ -1,24 +1,22 @@
package core.game.shops package core.game.shops
import core.ServerConstants
import core.api.* import core.api.*
import core.game.component.Component
import core.game.container.*
import core.game.container.Container
import core.game.event.ItemShopPurchaseEvent import core.game.event.ItemShopPurchaseEvent
import core.game.event.ItemShopSellEvent import core.game.event.ItemShopSellEvent
import core.game.component.Component
import core.game.container.Container
import core.game.container.ContainerEvent
import core.game.container.ContainerListener
import core.game.container.ContainerType
import core.game.node.entity.player.Player import core.game.node.entity.player.Player
import core.game.node.item.Item import core.game.node.item.Item
import core.game.shops.Shops.Companion.logShop
import core.game.system.config.ItemConfigParser
import core.game.world.GameWorld
import core.net.packet.PacketRepository import core.net.packet.PacketRepository
import core.net.packet.context.ContainerContext import core.net.packet.context.ContainerContext
import core.net.packet.out.ContainerPacket import core.net.packet.out.ContainerPacket
import org.rs09.consts.Components import org.rs09.consts.Components
import org.rs09.consts.Items import org.rs09.consts.Items
import core.ServerConstants
import core.game.shops.Shops.Companion.logShop
import core.game.system.config.ItemConfigParser
import core.game.world.GameWorld
import java.lang.Integer.max import java.lang.Integer.max
import java.lang.Integer.min import java.lang.Integer.min
import kotlin.math.ceil import kotlin.math.ceil
@ -338,7 +336,8 @@ class Shop(val title: String, val stock: Array<ShopItem>, val general: Boolean =
} }
else else
{ {
sendMessage(player, "You don't have enough ${cost.name.toLowerCase()} to buy that many.") sendMessage(player, "You don't have enough ${cost.name.lowercase()} to buy that many.")
return TransactionStatus.Failure("Not enough money in inventory")
} }
player.dispatch(ItemShopPurchaseEvent(item.id, item.amount, cost)) player.dispatch(ItemShopPurchaseEvent(item.id, item.amount, cost))

View file

@ -1,23 +1,25 @@
package core.game.shops package core.game.shops
import content.global.skill.crafting.TanningProduct
import core.ServerConstants
import core.api.* import core.api.*
import core.game.ge.GrandExchange
import core.game.interaction.IntType
import core.game.interaction.InteractionListener
import core.game.interaction.InterfaceListener
import core.game.node.entity.npc.NPC import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player import core.game.node.entity.player.Player
import content.global.skill.crafting.TanningProduct import core.game.system.command.Privilege
import core.tools.END_DIALOGUE
import core.tools.Log
import core.tools.secondsToTicks
import org.json.simple.JSONArray import org.json.simple.JSONArray
import org.json.simple.JSONObject import org.json.simple.JSONObject
import org.json.simple.parser.JSONParser import org.json.simple.parser.JSONParser
import org.rs09.consts.Components import org.rs09.consts.Components
import org.rs09.consts.Items import org.rs09.consts.Items
import org.rs09.consts.NPCs import org.rs09.consts.NPCs
import core.ServerConstants
import core.game.interaction.InteractionListener
import core.game.interaction.IntType
import core.game.interaction.InterfaceListener
import core.game.system.command.Privilege
import java.io.FileReader import java.io.FileReader
import core.tools.*
import core.game.ge.*
/** /**
* The "controller" class for shops. Handles opening shops from various NPC interactions and updating stock, etc. * The "controller" class for shops. Handles opening shops from various NPC interactions and updating stock, etc.
@ -154,6 +156,15 @@ class Shops : StartupListener, TickListener, InteractionListener, InterfaceListe
} }
return@on true return@on true
} }
on(NPCs.CANDLE_MAKER_562, IntType.NPC, "trade") { player, node ->
if (getQuestStage(player, "Merlin's Crystal") > 60) {
openId(player, 56)
} else {
shopsByNpc[node.id]?.openFor(player)
}
return@on true
}
} }
override fun defineInterfaceListeners() { override fun defineInterfaceListeners() {
@ -179,7 +190,7 @@ class Shops : StartupListener, TickListener, InteractionListener, InterfaceListe
when(opcode) when(opcode)
{ {
OP_VALUE -> sendMessage(player, "${getItemName(if (isMainStock) shop.stock[slot].itemId else shop.playerStock[slot].id)}: This item currently costs ${price.amount} ${price.name.toLowerCase()}.") OP_VALUE -> sendMessage(player, "${getItemName(if (isMainStock) shop.stock[slot].itemId else shop.playerStock[slot].id)}: This item currently costs ${price.amount} ${price.name.lowercase()}.")
OP_BUY_1 -> shop.buy(player, slot, 1) OP_BUY_1 -> shop.buy(player, slot, 1)
OP_BUY_5 -> shop.buy(player, slot, 5) OP_BUY_5 -> shop.buy(player, slot, 5)
OP_BUY_10 -> shop.buy(player, slot, 10) OP_BUY_10 -> shop.buy(player, slot, 10)

View file

@ -1,11 +1,12 @@
import core.game.node.entity.player.link.IronmanMode import core.game.node.entity.player.link.IronmanMode
import core.game.node.item.Item import core.game.node.item.Item
import core.game.shops.Shop
import core.game.shops.Shops
import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.rs09.consts.Items import org.rs09.consts.Items
import core.game.shops.Shop
import core.game.shops.Shops
import kotlin.math.min import kotlin.math.min
import kotlin.math.roundToInt import kotlin.math.roundToInt
@ -228,7 +229,7 @@ class ShopTests {
} }
@Test fun shouldAllowStandardPlayerToBuy() { @Test fun shouldAllowStandardPlayerToBuy() {
testPlayer.inventory.add(Item(995, 100000)) testPlayer.inventory.add(Item(995, 125000))
testPlayer.setAttribute("shop-cont", general.getContainer(testPlayer)) testPlayer.setAttribute("shop-cont", general.getContainer(testPlayer))
testPlayer.setAttribute("shop-main", true) testPlayer.setAttribute("shop-main", true)
val status = general.buy(testPlayer, 0, 1) val status = general.buy(testPlayer, 0, 1)
@ -236,7 +237,7 @@ class ShopTests {
} }
@Test fun shouldAllowStandardPlayerToBuyOverstock() { @Test fun shouldAllowStandardPlayerToBuyOverstock() {
testPlayer.inventory.add(Item(995, 100000)) testPlayer.inventory.add(Item(995, 125000))
testPlayer.setAttribute("shop-cont", general.getContainer(testPlayer)) testPlayer.setAttribute("shop-cont", general.getContainer(testPlayer))
testPlayer.setAttribute("shop-main", true) testPlayer.setAttribute("shop-main", true)
general.getContainer(testPlayer).add(Item(4151, 100)) general.getContainer(testPlayer).add(Item(4151, 100))
@ -245,7 +246,7 @@ class ShopTests {
} }
@Test fun shouldAllowStandardPlayerToBuyPlayerStock() { @Test fun shouldAllowStandardPlayerToBuyPlayerStock() {
testPlayer.inventory.add(Item(995, 100000)) testPlayer.inventory.add(Item(995, 125000))
testPlayer.setAttribute("shop-cont", general.getContainer(testPlayer)) testPlayer.setAttribute("shop-cont", general.getContainer(testPlayer))
testPlayer.setAttribute("shop-main", false) testPlayer.setAttribute("shop-main", false)
general.playerStock.add(Item(4151, 100)) general.playerStock.add(Item(4151, 100))