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;
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.link.diary.DiaryType;
import core.game.node.entity.skill.SkillPulse;
@ -11,6 +14,9 @@ import core.game.world.update.flag.context.Animation;
import core.tools.StringUtils;
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.
* @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.dispatch(new ResourceProducedEvent(dairy.getProduct().getId(), amount, node, BUCKET_OF_MILK.getId()));
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;
}
}

View file

@ -9,9 +9,9 @@ import content.global.skill.skillcapeperks.SkillcapePerks.Companion.isActive
import content.global.skill.summoning.familiar.Forager
import core.api.*
import core.game.event.ResourceProducedEvent
import core.game.interaction.Clocks
import core.game.interaction.IntType
import core.game.interaction.InteractionListener
import core.game.interaction.Clocks
import core.game.node.Node
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
@ -42,6 +42,7 @@ class FishingListener : InteractionListener{
val npc = node as? NPC ?: return clearScripts(player)
val spot = FishingSpot.forId(npc.id) ?: return clearScripts(player)
val op = spot.getOptionByName(getUsedOption(player)) ?: return clearScripts(player)
var forager: Forager? = null
if (player.familiarManager.hasFamiliar() && player.familiarManager.familiar is Forager) {
@ -58,8 +59,21 @@ class FishingListener : InteractionListener{
val dest = player.location.transform(player.direction)
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...")
}
}
}
if (clockReady(player, Clocks.SKILLING)) {
anim(player, op)
@ -72,11 +86,15 @@ class FishingListener : InteractionListener{
val bigFishId = Fish.getBigFish(fish)
val bigFishChance = if (GameWorld.settings?.isDevMode == true) 10 else 5000
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)
} else {
var msg = if (fish == Fish.ANCHOVIE || fish == Fish.SHRIMP) "You catch some" else "You catch a"
msg += getItemName(fish!!.id).lowercase().replace("raw", "").replace("big", "")
var msg = when (fish) {
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 "."
sendMessage(player, msg)
addItemOrDrop(player, item.id, item.amount)
@ -109,20 +127,29 @@ class FishingListener : InteractionListener{
private fun checkRequirements(player: Player, option: FishingOption, node: Node) : Boolean {
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
}
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
}
if (player.skills.getLevel(Skills.FISHING) < option!!.level) {
val f = option!!.fish[option!!.fish.size - 1]
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 <= ' ' })
if (!hasLevelDyn(player, Skills.FISHING, option.level)) {
sendDialogue(player, "You need a Fishing level of at least ${option.level} to ${option.option} these fish.")
return false
}
if (player.inventory.freeSlots() == 0) {
player.dialogueInterpreter.sendDialogue("You don't have enough space in your inventory.")
if (freeSlots(player) == 0) {
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 node.isActive && node.location.withinDistance(player.location, 1)

View file

@ -1,31 +1,29 @@
package content.global.skill.gather.fishing
import core.game.event.ResourceProducedEvent
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.FishingOption
import content.global.skill.skillcapeperks.SkillcapePerks
import content.global.skill.skillcapeperks.SkillcapePerks.Companion.isActive
import content.global.skill.summoning.familiar.Forager
import core.api.addItem
import core.api.getItemName
import core.api.inEquipment
import core.api.inInventory
import core.api.*
import core.game.event.ResourceProducedEvent
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 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.world.GameWorld.Pulser
import core.game.world.map.Location
import core.game.world.map.path.Pathfinder
import core.game.world.update.flag.context.Animation
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 org.rs09.consts.Items
/**
* 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())
if (!inInventory(player, option.tool) && !hasBarbTail()) {
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)
stop()
return false
}
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()
return false
}
if (player.skills.getLevel(Skills.FISHING) < option!!.level) {
val f = option!!.fish[option!!.fish.size - 1]
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 <= ' ' })
if (!hasLevelDyn(player, Skills.FISHING, option.level)) {
sendDialogue(player, "You need a Fishing level of at least ${option.level} to ${option.option} these fish.")
stop()
return false
}
if (player.inventory.freeSlots() == 0) {
player.dialogueInterpreter.sendDialogue("You don't have enough space in your inventory.")
if (freeSlots(player) == 0) {
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()
return false
}
@ -240,15 +246,23 @@ class FishingPulse(player: Player?, npc: NPC, private val option: FishingOption?
override fun message(type: Int) {
when (type) {
0 -> player.packetDispatch.sendMessage(option!!.getStartMessage())
0 -> sendMessage(player, option!!.getStartMessage())
2 -> {
player.packetDispatch.sendMessage(
if (fish == Fish.ANCHOVIE || fish == Fish.SHRIMP) "You catch some " + getItemName(fish!!.id).lowercase()
.replace("raw", "")
.trim { it <= ' ' } + "." else "You catch a " + getItemName(fish!!.id).lowercase()
.replace("raw", "").trim { it <= ' ' } + ".")
var msg = when (fish) {
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 "."
sendMessage(player, msg)
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()
}
}

View file

@ -1,9 +1,12 @@
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.UseWithHandler
import core.game.node.entity.skill.SkillPulse
import content.global.skill.herblore.GrindingItem
import core.game.node.item.Item
import core.game.world.update.flag.context.Animation
import core.net.packet.PacketRepository
@ -11,7 +14,9 @@ import core.net.packet.context.ChildPositionContext
import core.net.packet.out.RepositionChild
import core.plugin.Initializable
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.
@ -30,14 +35,19 @@ class GrindItemPlugin : UseWithHandler(233) {
override fun handle(event: NodeUsageEvent): Boolean {
val grind = GrindingItem.forItem(if (event.usedItem.id == 233) event.baseItem else event.usedItem)
val handler = object : SkillDialogueHandler(event.player,SkillDialogue.ONE_OPTION,grind.product){
val handler = object : SkillDialogueHandler(event.player,SkillDialogue.ONE_OPTION,grind.product) {
override fun create(amount: Int, index: Int) {
player.pulseManager.run(object : SkillPulse<Item>(player,event.usedItem){
player.pulseManager.run(object : SkillPulse<Item>(player,event.usedItem) {
var amt = 0
init {
amt = amount
if(amt > player.inventory.getAmount(node)){
amt = player.inventory.getAmount(node)
if(amt > amountInInventory(player, node.id)) {
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)
}
@ -50,8 +60,20 @@ class GrindItemPlugin : UseWithHandler(233) {
}
override fun reward(): Boolean {
if(player.inventory.remove(node)){
player.inventory.add(GrindingItem.forItem(node).product)
if (node.id == Items.FISHING_BAIT_313) {
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--
return amt <= 0
@ -61,7 +83,7 @@ class GrindItemPlugin : UseWithHandler(233) {
}
override fun getAll(index: Int): Int {
return player.inventory.getAmount(event.usedItem)
return amountInInventory(player, event.usedItem.id)
}
}
handler.open()
@ -74,5 +96,6 @@ class GrindItemPlugin : UseWithHandler(233) {
* Represents the animation to use.
*/
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
*/
public enum GrindingItem {
UNICORN_HORN(new Item[] { new Item(237) },new Item(235)),
KEBBIT_TEETH(new Item[] { new Item(10109) }, new Item(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)),
GOAT_HORN(new Item[] { new Item(9735) }, new Item(9736)),
MUD_RUNE(new Item[] { new Item(4698) }, new Item(9594)),
ASHES(new Item[] { new Item(592) }, new Item(8865)),
POISON_KARAMBWAN(new Item[] { new Item(3146) }, new Item(3152)),
FISHING_BAIT(new Item[] { new Item(313) }, new Item(12129)),
SEAWEED(new Item[] { new Item(401) }, new Item(6683)),
BAT_BONES(new Item[] { new Item(530) }, new Item(2391)),
CHARCOAL(new Item[] { new Item(973) }, new Item(704)),
ASTRAL_RUNE_SHARDS(new Item[] { new Item(11156) }, new Item(11155)),
GARLIC(new Item[] { new Item(1550) }, new Item(4668)),
DRAGON_SCALE(new Item[] { new Item(243) }, new Item(241)),
ANCHOVIES(new Item[] { new Item(319) }, new Item(11266)),
UNICORN_HORN(new Item[] { new Item(Items.UNICORN_HORN_237) }, new Item(Items.UNICORN_HORN_DUST_235)),
KEBBIT_TEETH(new Item[] { new Item(Items.KEBBIT_TEETH_10109) }, new Item(Items.KEBBIT_TEETH_DUST_10111)),
BIRDS_NEST(new Item[] { new Item(Items.BIRDS_NEST_5075) }, new Item(Items.CRUSHED_NEST_6693)),
GOAT_HORN(new Item[] { new Item(Items.DESERT_GOAT_HORN_9735) }, new Item(Items.GOAT_HORN_DUST_9736)),
MUD_RUNE(new Item[] { new Item(Items.MUD_RUNE_4698) }, new Item(Items.GROUND_MUD_RUNES_9594)),
ASHES(new Item[] { new Item(Items.ASHES_592) }, new Item(Items.GROUND_ASHES_8865)),
POISON_KARAMBWAN(new Item[] { new Item(Items.POISON_KARAMBWAN_3146) }, new Item(Items.KARAMBWAN_PASTE_3152)),
FISHING_BAIT(new Item[] { new Item(Items.FISHING_BAIT_313) }, new Item(Items.GROUND_FISHING_BAIT_12129)),
SEAWEED(new Item[] { new Item(Items.SEAWEED_401) }, new Item(Items.GROUND_SEAWEED_6683)),
BAT_BONES(new Item[] { new Item(Items.BAT_BONES_530) }, new Item(Items.GROUND_BAT_BONES_2391)),
CHARCOAL(new Item[] { new Item(Items.CHARCOAL_973) }, new Item(Items.GROUND_CHARCOAL_704)),
ASTRAL_RUNE_SHARDS(new Item[] { new Item(Items.ASTRAL_RUNE_SHARDS_11156) }, new Item(Items.GROUND_ASTRAL_RUNE_11155)),
GARLIC(new Item[] { new Item(Items.GARLIC_1550) }, new Item(Items.GARLIC_POWDER_4668)),
DRAGON_SCALE(new Item[] { new Item(Items.BLUE_DRAGON_SCALE_243) }, new Item(Items.DRAGON_SCALE_DUST_241)),
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)),
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;
import core.game.event.ResourceProducedEvent;
import core.game.node.entity.skill.SkillPulse;
import core.game.node.entity.skill.Skills;
import core.game.node.entity.npc.NPC;
@ -119,6 +120,7 @@ public final class StallThiefPulse extends SkillPulse<Scenery> {
return true;
}
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;
}

View file

@ -1,16 +1,9 @@
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.skill.cooking.dairy.DairyChurnDialogue
import content.minigame.barbassault.CaptainCainDialogue
import content.region.fremennik.jatizso.dialogue.TowerGuardDialogue
import content.region.fremennik.rellekka.dialogue.HuntingExpertRellekkaDialogue
import content.region.fremennik.rellekka.quest.thefremenniktrials.ChieftanBrundt
import core.api.inBorders
import core.api.inEquipment
@ -18,9 +11,12 @@ import core.game.diary.AreaDiaryTask
import core.game.diary.DiaryEventHookBase
import core.game.diary.DiaryLevel
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.diary.DiaryType
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) {
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,
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
@ -298,14 +296,6 @@ class FremennikAchievementDiary : DiaryEventHookBase(DiaryType.FREMENNIK) {
override fun onInteracted(player: Player, event: InteractionEvent) {
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") {
finishTask(
player,

View file

@ -1,12 +1,5 @@
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.item.withnpc.PoisonChaliceOnKingArthurDialogue
import core.api.inBorders
@ -14,8 +7,15 @@ import core.api.inEquipment
import core.game.diary.DiaryEventHookBase
import core.game.diary.DiaryLevel
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 {
private const val ATTRIBUTE_CUT_YEW_COUNT = "diary:seers:cut-yew"
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
)
private val CHURN_PRODUCT = arrayOf(
Items.CHEESE_1985, Items.POT_OF_CREAM_2130, Items.PAT_OF_BUTTER_6697
)
object EasyTasks {
const val PICK_5_FLAX = 0
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) {
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) {
progressIncrementalTask(
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();
Quest quest = player.getQuestRepository().getQuest("Merlin's Crystal");
if (quest.getStage(player) > 60) {
Shops.openId(player, 198);
Shops.openId(player, 56);
} else {
npc.openShop(player);
}
@ -175,7 +175,7 @@ public final class CandleMakerDialogue extends DialoguePlugin {
case 30:
end();
if (quest.getStage(player) > 60) {
Shops.openId(player, 198);
Shops.openId(player, 56);
} else {
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.FacialExpression;
@ -13,7 +13,7 @@ import core.game.node.item.Item;
* @version 1.0
*/
@Initializable
public final class CandleSellerPlugin extends DialoguePlugin {
public final class CandleSellerDialogue extends DialoguePlugin {
/**
* Represents the coins item.
@ -28,7 +28,7 @@ public final class CandleSellerPlugin extends DialoguePlugin {
/**
* Constructs a new {@code CandleSellerPlugin} {@code Object}.
*/
public CandleSellerPlugin() {
public CandleSellerDialogue() {
/**
* empty.
*/
@ -38,13 +38,13 @@ public final class CandleSellerPlugin extends DialoguePlugin {
* Constructs a new {@code CandleSellerPlugin} {@code Object}.
* @param player the player.
*/
public CandleSellerPlugin(Player player) {
public CandleSellerDialogue(Player player) {
super(player);
}
@Override
public DialoguePlugin newInstance(Player player) {
return new CandleSellerPlugin(player);
return new CandleSellerDialogue(player);
}
@Override

View file

@ -1,24 +1,22 @@
package core.game.shops
import core.ServerConstants
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.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.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.context.ContainerContext
import core.net.packet.out.ContainerPacket
import org.rs09.consts.Components
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.min
import kotlin.math.ceil
@ -240,7 +238,7 @@ class Shop(val title: String, val stock: Array<ShopItem>, val general: Boolean =
val price: Int = ceil(item.definition.value * mod.toDouble() / 100.0).toInt()
/* if(player.getVarp(532) == 6529){
/* if(player.getVarp(532) == 6529){
price = 3 * price / 2
}*/
return max(price, 1)
@ -338,7 +336,8 @@ class Shop(val title: String, val stock: Array<ShopItem>, val general: Boolean =
}
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))

View file

@ -1,23 +1,25 @@
package core.game.shops
import content.global.skill.crafting.TanningProduct
import core.ServerConstants
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.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.JSONObject
import org.json.simple.parser.JSONParser
import org.rs09.consts.Components
import org.rs09.consts.Items
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 core.tools.*
import core.game.ge.*
/**
* 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
}
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() {
@ -179,7 +190,7 @@ class Shops : StartupListener, TickListener, InteractionListener, InterfaceListe
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_5 -> shop.buy(player, slot, 5)
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.item.Item
import core.game.shops.Shop
import core.game.shops.Shops
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.rs09.consts.Items
import core.game.shops.Shop
import core.game.shops.Shops
import kotlin.math.min
import kotlin.math.roundToInt
@ -228,7 +229,7 @@ class ShopTests {
}
@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-main", true)
val status = general.buy(testPlayer, 0, 1)
@ -236,7 +237,7 @@ class ShopTests {
}
@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-main", true)
general.getContainer(testPlayer).add(Item(4151, 100))
@ -245,7 +246,7 @@ class ShopTests {
}
@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-main", false)
general.playerStock.add(Item(4151, 100))