Vinesweeper improvements

Added missing animations
NPCs perform their animations and chatlines in proper sequence and timing
Added in the 2 other colors of bunnies, so now all 3 colors of bunnies are present
Added in 3 new use-with item interactions: spade on hole, flag on hole, ogleroot on bunny
Prevent bunnies from being double dipped for hunter XP
Planting a flag now locks the player for the duration of the animation
This commit is contained in:
Lila Hioh 2022-07-30 15:37:39 +00:00 committed by Ryan
parent 4ff7d347b5
commit 3145af75a6
4 changed files with 266 additions and 316 deletions

View file

@ -63096,6 +63096,7 @@
"examine": "A hungry-looking rabbit.",
"melee_animation": "0",
"range_animation": "0",
"respawn_delay": "50",
"defence_animation": "0",
"magic_animation": "0",
"death_animation": "0",
@ -63126,23 +63127,6 @@
"range_level": "1",
"attack_level": "1"
},
{
"examine": "A gnome farmer.",
"melee_animation": "0",
"range_animation": "0",
"defence_animation": "0",
"magic_animation": "0",
"death_animation": "0",
"name": "Farmer",
"defence_level": "1",
"safespot": null,
"lifepoints": "10",
"strength_level": "1",
"id": "7129",
"aggressive": "true",
"range_level": "1",
"attack_level": "1"
},
{
"examine": "A gnome farmer.",
"melee_animation": "0",
@ -113532,6 +113516,7 @@
"examine": "A hungry-looking rabbit.",
"melee_animation": "0",
"range_animation": "0",
"respawn_delay": "50",
"defence_animation": "0",
"magic_animation": "0",
"death_animation": "0",
@ -113540,24 +113525,7 @@
"safespot": null,
"lifepoints": "10",
"strength_level": "1",
"id": "7125",
"aggressive": "true",
"range_level": "1",
"attack_level": "1"
},
{
"examine": "A gnome farmer.",
"melee_animation": "0",
"range_animation": "0",
"defence_animation": "0",
"magic_animation": "0",
"death_animation": "0",
"name": "Farmer",
"defence_level": "1",
"safespot": null,
"lifepoints": "10",
"strength_level": "1",
"id": "7128",
"id": "7126",
"aggressive": "true",
"range_level": "1",
"attack_level": "1"
@ -113579,23 +113547,6 @@
"range_level": "1",
"attack_level": "1"
},
{
"examine": "A gnome farmer.",
"melee_animation": "0",
"range_animation": "0",
"defence_animation": "0",
"magic_animation": "0",
"death_animation": "0",
"name": "Farmer",
"defence_level": "1",
"safespot": null,
"lifepoints": "10",
"strength_level": "1",
"id": "7130",
"aggressive": "true",
"range_level": "1",
"attack_level": "1"
},
{
"agg_radius": "64",
"examine": "That's one big Ork... ",
@ -163399,6 +163350,7 @@
"examine": "A hungry-looking rabbit.",
"melee_animation": "0",
"range_animation": "0",
"respawn_delay": "50",
"defence_animation": "0",
"magic_animation": "0",
"death_animation": "0",
@ -163407,58 +163359,7 @@
"safespot": null,
"lifepoints": "10",
"strength_level": "1",
"id": "7125",
"aggressive": "true",
"range_level": "1",
"attack_level": "1"
},
{
"examine": "A gnome farmer.",
"melee_animation": "0",
"range_animation": "0",
"defence_animation": "0",
"magic_animation": "0",
"death_animation": "0",
"name": "Farmer",
"defence_level": "1",
"safespot": null,
"lifepoints": "10",
"strength_level": "1",
"id": "7128",
"aggressive": "true",
"range_level": "1",
"attack_level": "1"
},
{
"examine": "A gnome farmer.",
"melee_animation": "0",
"range_animation": "0",
"defence_animation": "0",
"magic_animation": "0",
"death_animation": "0",
"name": "Farmer",
"defence_level": "1",
"safespot": null,
"lifepoints": "10",
"strength_level": "1",
"id": "7129",
"aggressive": "true",
"range_level": "1",
"attack_level": "1"
},
{
"examine": "A gnome farmer.",
"melee_animation": "0",
"range_animation": "0",
"defence_animation": "0",
"magic_animation": "0",
"death_animation": "0",
"name": "Farmer",
"defence_level": "1",
"safespot": null,
"lifepoints": "10",
"strength_level": "1",
"id": "7130",
"id": "7127",
"aggressive": "true",
"range_level": "1",
"attack_level": "1"
@ -212255,74 +212156,6 @@
"range_level": "1",
"attack_level": "1"
},
{
"examine": "A hungry-looking rabbit.",
"melee_animation": "0",
"range_animation": "0",
"defence_animation": "0",
"magic_animation": "0",
"death_animation": "0",
"name": "Rabbit",
"defence_level": "1",
"safespot": null,
"lifepoints": "10",
"strength_level": "1",
"id": "7125",
"aggressive": "true",
"range_level": "1",
"attack_level": "1"
},
{
"examine": "A gnome farmer.",
"melee_animation": "0",
"range_animation": "0",
"defence_animation": "0",
"magic_animation": "0",
"death_animation": "0",
"name": "Farmer",
"defence_level": "1",
"safespot": null,
"lifepoints": "10",
"strength_level": "1",
"id": "7128",
"aggressive": "true",
"range_level": "1",
"attack_level": "1"
},
{
"examine": "A gnome farmer.",
"melee_animation": "0",
"range_animation": "0",
"defence_animation": "0",
"magic_animation": "0",
"death_animation": "0",
"name": "Farmer",
"defence_level": "1",
"safespot": null,
"lifepoints": "10",
"strength_level": "1",
"id": "7129",
"aggressive": "true",
"range_level": "1",
"attack_level": "1"
},
{
"examine": "A gnome farmer.",
"melee_animation": "0",
"range_animation": "0",
"defence_animation": "0",
"magic_animation": "0",
"death_animation": "0",
"name": "Farmer",
"defence_level": "1",
"safespot": null,
"lifepoints": "10",
"strength_level": "1",
"id": "7130",
"aggressive": "true",
"range_level": "1",
"attack_level": "1"
},
{
"agg_radius": "64",
"examine": "That's one big Ork... ",
@ -220454,11 +220287,6 @@
"name": "Farmer Blinkin",
"id": "7131"
},
{
"examine": "Owner of this homestead.",
"name": "Mrs. Winkin",
"id": "7132"
},
{
"examine": "The lady of the pet shop.",
"name": "Pet shop owner",

View file

@ -10985,7 +10985,15 @@
},
{
"npc_id": "7125",
"loc_data": "{1605,4702,0,1,0}-{1605,4720,0,1,0}-{1631,4730,0,1,0}-{1649,4730,0,1,0}-{1658,4705,0,1,0}-{1658,4687,0,1,0}-{1633,4678,0,1,0}-{1615,4678,0,1,0}"
"loc_data": "{1605,4702,0,1,0}-{1649,4730,0,1,0}"
},
{
"npc_id": "7126",
"loc_data": "{1605,4720,0,1,0}-{1658,4705,0,1,0}-{1633,4678,0,1,0}"
},
{
"npc_id": "7127",
"loc_data": "{1631,4730,0,1,0}-{1658,4687,0,1,0}-{1615,4678,0,1,0}"
},
{
"npc_id": "7128",

View file

@ -1,25 +1,19 @@
package rs09.game.content.activity.vinesweeper
import BlinkinDialogue
import FarmerDialogue.Companion.FARMER_FLAG_LINES
import WinkinDialogue
import rs09.game.content.activity.vinesweeper.Vinesweeper.Companion.DEAD_PLANT_OBJ
import rs09.game.content.activity.vinesweeper.Vinesweeper.Companion.FARMERS
import rs09.game.content.activity.vinesweeper.Vinesweeper.Companion.FARMER_CLEAR_RADIUS
import rs09.game.content.activity.vinesweeper.Vinesweeper.Companion.HOLES
import rs09.game.content.activity.vinesweeper.Vinesweeper.Companion.NUMBERS
import rs09.game.content.activity.vinesweeper.Vinesweeper.Companion.RABBIT
import rs09.game.content.activity.vinesweeper.Vinesweeper.Companion.SEED_LOCS
import rs09.game.content.activity.vinesweeper.Vinesweeper.Companion.populateSeeds
import rs09.game.content.activity.vinesweeper.Vinesweeper.Companion.scheduleNPCs
import rs09.game.content.activity.vinesweeper.Vinesweeper.Companion.sendUpdatedPoints
import api.*
import core.game.component.Component
import core.game.interaction.DestinationFlag
import core.game.interaction.MovementPulse
import core.game.node.entity.Entity
import core.game.node.entity.combat.DeathTask
import core.game.node.entity.impl.Projectile
import core.game.node.entity.npc.AbstractNPC
import core.game.node.entity.npc.NPC
import core.game.node.entity.player.Player
import core.game.node.entity.skill.Skills;
import core.game.node.entity.skill.Skills
import core.game.node.item.GroundItemManager
import core.game.node.item.Item
import core.game.node.scenery.Scenery
@ -27,16 +21,32 @@ import core.game.node.scenery.SceneryBuilder
import core.game.system.task.Pulse
import core.game.world.map.Location
import core.game.world.map.RegionManager
import core.game.world.map.path.Pathfinder
import core.game.world.map.zone.ZoneBorders
import core.game.world.update.flag.context.Animation;
import core.game.world.update.flag.context.Graphics;
import core.game.world.update.flag.context.Animation
import core.game.world.update.flag.context.Graphics
import core.game.world.update.flag.player.FaceLocationFlag
import core.plugin.Initializable
import core.tools.RandomFunction
import org.rs09.consts.Animations
import org.rs09.consts.Components
import org.rs09.consts.Items
import org.rs09.consts.NPCs
import rs09.game.content.activity.vinesweeper.Vinesweeper.Companion.FARMERS
import rs09.game.content.activity.vinesweeper.Vinesweeper.Companion.FARMER_CLEAR_RADIUS
import rs09.game.content.activity.vinesweeper.Vinesweeper.Companion.HOLES
import rs09.game.content.activity.vinesweeper.Vinesweeper.Companion.NUMBERS
import rs09.game.content.activity.vinesweeper.Vinesweeper.Companion.RABBITS
import rs09.game.content.activity.vinesweeper.Vinesweeper.Companion.SEED_LOCS
import rs09.game.content.activity.vinesweeper.Vinesweeper.Companion.populateSeeds
import rs09.game.content.activity.vinesweeper.Vinesweeper.Companion.scheduleNPCs
import rs09.game.content.activity.vinesweeper.Vinesweeper.Companion.sendPoints
import rs09.game.interaction.InteractionListener
import rs09.game.interaction.InterfaceListener
import rs09.game.world.GameWorld;
import rs09.game.world.GameWorld
import rs09.game.world.GameWorld.ticks
import org.rs09.consts.Graphics as Gfx
import org.rs09.consts.Scenery as Sceneries
class Vinesweeper : InteractionListener, InterfaceListener, MapArea {
override fun defineAreaBorders(): Array<ZoneBorders> {
@ -74,7 +84,7 @@ class Vinesweeper : InteractionListener, InterfaceListener, MapArea {
override fun defineListeners() {
populateSeeds()
on(PORTAL, SCENERY, "enter") { player, _ ->
on(Sceneries.PORTAL_29534, SCENERY, "enter") { player, _ ->
val x = player.getAttribute("vinesweeper:return-tele:x", 3052)
val y = player.getAttribute("vinesweeper:return-tele:y", 3304)
teleport(player, Location(x, y))
@ -89,25 +99,47 @@ class Vinesweeper : InteractionListener, InterfaceListener, MapArea {
// TODO (crash): authenticity
player.sendMessage("You need a spade to dig here.")
} else {
player.visualize(Animation(8709), Graphics(1543))
player.visualize(Animation(Animations.HUMAN_VINESWEEPER_DIG_8709), Graphics(Gfx.VINESWEEPER_DIRT_DIG_1543))
dig(player, node.location)
}
return@on true
}
on(HOLES, SCENERY, "flag") { player, node ->
if(player.inventory.remove(Item(Items.FLAG_12625, 1))) {
player.sendMessage("You add a flag to the patch.")
val scenery = node as Scenery
SceneryBuilder.replace(scenery, scenery.transform(FLAG_OBJ))
scheduleNPCs(player, scenery.location, true, true)
} else {
// TODO (crash): authenticity
player.sendMessage("You do not have a flag to place in the patch.")
onUseWith(SCENERY,Items.SPADE_952,*HOLES) { player, _, with ->
player.visualize(Animation(Animations.HUMAN_VINESWEEPER_DIG_8709), Graphics(Gfx.VINESWEEPER_DIRT_DIG_1543))
dig(player, with.location)
return@onUseWith true
}
on(HOLES, SCENERY, "flag") { player, node ->
val hole = node as Scenery
var count = 0
if(player.location != node.location) {
plantFlag(player,hole)
return@on true
}
GameWorld.Pulser.submit(object : MovementPulse(player, hole, hole.destinationFlag) {
override fun pulse(): Boolean {
when(count++) {
0 -> {
player.faceLocation(hole.location)
return false
}
1 -> {
plantFlag(player,hole)
return true
}
}
return true
}
})
return@on true
}
onUseWith(SCENERY,Items.FLAG_12625,*HOLES) { player, _, with ->
val hole = with as Scenery
plantFlag(player,hole)
return@onUseWith true
}
on(HOLES, SCENERY, "inspect") { player, node ->
player.animate(Animation(8710))
player.animate(Animation(Animations.HUMAN_INSPECT_HOLE_8710))
player.lock(5)
GameWorld.Pulser.submit(object : Pulse(5) {
override fun pulse(): Boolean {
@ -128,54 +160,42 @@ class Vinesweeper : InteractionListener, InterfaceListener, MapArea {
})
return@on true
}
on(MRS_WINKIN, NPC, "talk-to") { player, npc ->
on(NPCs.MRS_WINKIN_7132, NPC, "talk-to") { player, npc ->
openDialogue(player, WinkinDialogue(), npc)
return@on true
}
on(MRS_WINKIN, NPC, "trade") { player, _ ->
on(NPCs.MRS_WINKIN_7132, NPC, "trade") { player, _ ->
player.interfaceManager.open(Component(686))
return@on true
}
on(MRS_WINKIN, NPC, "buy flags") { player, npc ->
on(NPCs.MRS_WINKIN_7132, NPC, "buy flags") { player, npc ->
val dialogue = WinkinDialogue()
dialogue.stage = 20
openDialogue(player, dialogue, npc)
return@on true
}
on(RABBIT, NPC, "feed") { player, node ->
if(player.inventory.remove(Item(Items.OGLEROOT_12624, 1))) {
val npc = node as NPC
// TODO: find burrow animation id
//npc.animate(9603)
npc.sendChat("Squeak!")
npc.lock(3)
GameWorld.Pulser.submit(object : Pulse(3) {
override fun pulse(): Boolean {
//npc.setInvisible(true)
player.skills.addExperience(Skills.HUNTER, 30.0)
npc.respawnTick = GameWorld.ticks + 50
npc.location = npc.properties.spawnLocation
return true
}
})
} else {
// TODO (crash): authenticity
player.sendMessage("You don't have any ogleroots to feed the rabbit.")
}
on(RABBITS, NPC, "feed") { player, node ->
val rabbit = node as NPC
feedRabbit(player,rabbit)
return@on true
}
on(FARMER_BLINKIN, NPC, "talk-to") { player, npc ->
onUseWith(NPC,Items.OGLEROOT_12624,*RABBITS) { player, _, with ->
val rabbit = with as NPC
feedRabbit(player,rabbit)
return@onUseWith true
}
on(NPCs.FARMER_BLINKIN_7131, NPC, "talk-to") { player, npc ->
//player.interfaceManager.open(Component(TUTORIAL))
openDialogue(player, BlinkinDialogue(), npc)
return@on true
}
on(FARMER_BLINKIN, NPC, "buy-flags") { player, npc ->
on(NPCs.FARMER_BLINKIN_7131, NPC, "buy-flags") { player, npc ->
val dialogue = BlinkinDialogue()
dialogue.stage = 21
openDialogue(player, dialogue, npc)
return@on true
}
on(FARMER_BLINKIN, NPC, "buy-roots") { player, npc ->
on(NPCs.FARMER_BLINKIN_7131, NPC, "buy-roots") { player, npc ->
val dialogue = BlinkinDialogue()
dialogue.stage = 40
openDialogue(player, dialogue, npc)
@ -254,12 +274,9 @@ class Vinesweeper : InteractionListener, InterfaceListener, MapArea {
companion object
{
val AVACH_NIMPORTO_LOC = Location.create(1637, 4709)
val PORTAL = 29534
val SIGNS = intArrayOf(29461, 29462, 29463, 29464)
val HOLES = intArrayOf(29476, 29477, 29478)
val SIGNS = intArrayOf(Sceneries.INSTRUCTION_SIGN_29461, Sceneries.INSTRUCTION_SIGN_29462, Sceneries.INSTRUCTION_SIGN_29463, Sceneries.INSTRUCTION_SIGN_29464)
val HOLES = intArrayOf(Sceneries.HOLE_29476, Sceneries.HOLE_29477, Sceneries.HOLE_29478)
val NUMBERS = intArrayOf(29447, 29448, 29449, 29450, 29451, 29452, 29453, 29454, 29455)
val DEAD_PLANT_OBJ = 29456
val FLAG_OBJ = 29457
val IFACE = 686
val TRADE_FOR_XP_BUTTON = 53
@ -337,10 +354,8 @@ class Vinesweeper : InteractionListener, InterfaceListener, MapArea {
29461 to 690
)
val RABBIT = 7125
val FARMERS = intArrayOf(7128, 7129, 7130)
val FARMER_BLINKIN = 7131
val MRS_WINKIN = 7132
val RABBITS = intArrayOf(NPCs.RABBIT_7125, NPCs.RABBIT_7126, NPCs.RABBIT_7127)
val FARMERS = intArrayOf(NPCs.FARMER_7128, NPCs.FARMER_7129, NPCs.FARMER_7130)
val MAX_SEEDS = 300
val FARMER_CLEAR_RADIUS = 3
@ -368,6 +383,51 @@ class Vinesweeper : InteractionListener, InterfaceListener, MapArea {
}
}
fun faceHole(player: Player, hole: Scenery) {
}
fun plantFlag(player: Player, hole: Scenery) {
if(player.inventory.remove(Item(Items.FLAG_12625, 1))) {
player.lock()
player.visualize(Animation(Animations.HUMAN_PLANT_FLAG_8711),Graphics(Gfx.VINESWEEPER_PLANT_FLAG_1541))
player.sendMessage("You add a flag to the patch.")
GameWorld.Pulser.submit(object : Pulse(2, player) {
override fun pulse(): Boolean {
SceneryBuilder.replace(hole, hole.transform(Sceneries.FLAG_29457))
scheduleNPCs(player, hole.location, true, true)
player.unlock()
return true
}
})
} else {
// TODO (crash): authenticity
player.sendMessage("You do not have a flag to place in the patch.")
}
}
fun feedRabbit(player: Player, rabbit: NPC) {
val respawnDelay = 50
if(rabbit.isInvisible || DeathTask.isDead(rabbit)) { return }
if(rabbit.getAttribute("dead", 0) > ticks) { return }
if(player.inventory.remove(Item(Items.OGLEROOT_12624, 1))) {
rabbit.setAttribute("dead",ticks + respawnDelay)
player.skills.addExperience(Skills.HUNTER, 30.0)
rabbit.sendChat("Squeak!")
rabbit.animate(Animation(Animations.RABBIT_EAT_OGLEROOT_8734))
rabbit.lock(3)
GameWorld.Pulser.submit(object : Pulse(3, player) {
override fun pulse(): Boolean {
rabbit.finalizeDeath(player)
rabbit.properties.teleportLocation = rabbit.properties.spawnLocation
return true
}
})
} else {
// TODO (crash): authenticity
player.sendMessage("You don't have any ogleroots to feed the rabbit.")
}
}
fun dig(player: Player, loc: Location) {
if(isSeed(loc)) {
val oldPoints = player.getAttribute("vinesweeper:points", 0)
@ -377,7 +437,7 @@ class Vinesweeper : InteractionListener, InterfaceListener, MapArea {
scheduleNPCs(player, loc, false, false)
val scenery = getScenery(loc)
if(scenery != null) {
SceneryBuilder.replace(scenery, scenery.transform(DEAD_PLANT_OBJ))
SceneryBuilder.replace(scenery, scenery.transform(Sceneries.DEAD_PLANT_29456))
}
} else {
player.incrementAttribute("/save:vinesweeper:points", 1)
@ -406,6 +466,20 @@ class Vinesweeper : InteractionListener, InterfaceListener, MapArea {
}
}
fun sendPoints(npc: NPC, dest: SeedDestination) {
val level = dest.player.skills.getStaticLevel(Skills.FARMING)
val points = RandomFunction.random(level, 4 * level)
dest.player.incrementAttribute("/save:vinesweeper:points", points)
dest.player.inventory.add(Item(Items.FLAG_12625, 1))
sendUpdatedPoints(dest.player)
for (neighbor in RegionManager.getLocalPlayers(npc)) {
if (neighbor != dest.player) {
neighbor.incrementAttribute("/save:vinesweeper:points", points / 2)
sendUpdatedPoints(neighbor)
}
}
}
fun isHole(loc: Location): Boolean {
val scenery = getScenery(loc)
return scenery != null && HOLES.contains(scenery.id)
@ -413,7 +487,7 @@ class Vinesweeper : InteractionListener, InterfaceListener, MapArea {
fun scheduleNPCs(player: Player, loc: Location, alive: Boolean, rabbit: Boolean) {
val dest = SeedDestination(player, loc, alive)
val ids = if(rabbit) { intArrayOf(RABBIT, *FARMERS) } else { FARMERS }
val ids = if(rabbit) { RABBITS + FARMERS } else { FARMERS }
for(npc in findLocalNPCs(player, ids, 30)) {
if(npc is VinesweeperNPC) {
npc.seedDestinations.add(dest)
@ -432,7 +506,7 @@ class Vinesweeper : InteractionListener, InterfaceListener, MapArea {
player.audioManager.send(125)
Projectile.create(npc, player, 109).send()
npc.sendChat("Avach nimporto!")
GameWorld.Pulser.submit(object : Pulse(1) {
GameWorld.Pulser.submit(object : Pulse(1, player) {
var counter = 0
override fun pulse(): Boolean {
when (counter++) {
@ -459,7 +533,7 @@ class Vinesweeper : InteractionListener, InterfaceListener, MapArea {
@Initializable
class VinesweeperNPC : AbstractNPC {
var seedDestinations: ArrayList<Vinesweeper.SeedDestination> = ArrayList();
constructor() : super(RABBIT, null, true) {}
constructor() : super(RABBITS[0], null, true) {}
private constructor(id: Int, location: Location) : super(id, location) {}
override fun construct(id: Int, location: Location, vararg objects: Any?): AbstractNPC {
return VinesweeperNPC(id, location)
@ -470,9 +544,8 @@ class VinesweeperNPC : AbstractNPC {
}
override fun getIds(): IntArray {
return intArrayOf(RABBIT, *FARMERS)
return RABBITS + FARMERS
}
override fun handleTickActions() {
val dest = seedDestinations.find { sd -> sd.loc == location }
if(dest != null) {
@ -484,24 +557,13 @@ class VinesweeperNPC : AbstractNPC {
}
val scenery = getScenery(dest.loc)
if(scenery != null) {
if(id == RABBIT) {
val replacement = if(SEED_LOCS.contains(dest.loc)) { DEAD_PLANT_OBJ } else { HOLES[0] }
SceneryBuilder.replace(scenery, scenery.transform(replacement))
scheduleNPCs(dest.player, dest.loc, alive = false, rabbit = false)
if(id in RABBITS) {
handleRabbitSeed(scenery, dest)
} else {
if(dest.alive) {
handleFarmerFlag(scenery, dest)
} else {
sendChat("Hmm. Looks like there's a plant here.")
lock(3)
GameWorld.Pulser.submit(object : Pulse(3) {
override fun pulse(): Boolean {
sendChat("Gracious me! This one's dead")
SceneryBuilder.replace(scenery, scenery.transform(HOLES[0]))
farmerClear(dest)
return true
}
})
handleFarmerSeed(scenery, dest)
}
}
}
@ -519,48 +581,91 @@ class VinesweeperNPC : AbstractNPC {
}
}
fun handleFarmerFlag(scenery: Scenery, dest: Vinesweeper.SeedDestination) {
sendChat("Ah, another flag to clear. Let's see what's there.")
lock(3)
animate(Animation(451))
fun handleRabbitSeed(scenery: Scenery, dest: Vinesweeper.SeedDestination) {
if(SEED_LOCS.contains(dest.loc)) {
val npc = this
val replacement = Sceneries.DEAD_PLANT_29456
lock(4)
animate(Animation(Animations.RABBIT_EAT_SEED_8718))
SceneryBuilder.replace(scenery, scenery.transform(replacement))
scheduleNPCs(dest.player, dest.loc, alive = false, rabbit = false)
} else {
scheduleNPCs(dest.player, dest.loc, alive = true, rabbit = false)
}
}
fun handleFarmerSeed(scenery: Scenery, dest: Vinesweeper.SeedDestination) {
lock()
var i = 0
animate(Animation(Animations.GNOME_FARMER_DIG_SEED_8730))
GameWorld.Pulser.submit(object: Pulse(3) {
override fun pulse(): Boolean {
sendChat("Ah! A seed. Points for everyone near me!")
val level = dest.player.skills.getStaticLevel(Skills.FARMING)
val points = RandomFunction.random(level, 4 * level)
dest.player.incrementAttribute("/save:vinesweeper:points", points)
dest.player.inventory.add(Item(Items.FLAG_12625, 1))
sendUpdatedPoints(dest.player)
for(neighbor in RegionManager.getLocalPlayers(npc)) {
if(neighbor != dest.player) {
neighbor.incrementAttribute("/save:vinesweeper:points", points / 2)
sendUpdatedPoints(neighbor)
}
when(i++) {
0 -> {
sendChat(FARMER_FLAG_LINES.FIND_PLANT.line)
}
1 -> {
animate(Animation(Animations.GNOME_FARMER_SPADE_SMACK_8732))
sendChat(FARMER_FLAG_LINES.DEAD_PLANT.line)
SceneryBuilder.replace(scenery, scenery.transform(HOLES[0]))
}
2 -> {
animate(Animation(Animations.GNOME_FARMER_CLEAR_HOLES_8724))
farmerClear(dest)
}
3 -> {
unlock()
return true
}
}
return false
}
})
} else {
SceneryBuilder.replace(scenery, scenery.transform(HOLES[0]))
}
fun handleFarmerFlag(scenery: Scenery, dest: Vinesweeper.SeedDestination) {
val npc = this
lock()
var i = 0
val lines = arrayOf("Hmm, no seeds planted here, I'm afraid.", "I'll have to keep this 'ere flag. Sorry.")
animate(Animation(Animations.GNOME_FARMER_DIG_FLAG_8725))
GameWorld.Pulser.submit(object: Pulse(3) {
override fun pulse(): Boolean {
sendChat(lines[i++])
return i >= lines.size
when(i++) {
0 -> {
sendChat(FARMER_FLAG_LINES.FIND_FLAG.line)
}
1 -> {
SceneryBuilder.replace(scenery, scenery.transform(HOLES[0]))
if(SEED_LOCS.contains(dest.loc)) {
sendChat(FARMER_FLAG_LINES.FIND_SEED.line)
animate(Animation(Animations.GNOME_FARMER_HOORAY_8731))
sendPoints(npc,dest)
i++
} else {
sendChat(FARMER_FLAG_LINES.NO_SEED.line)
}
}
2 -> {
sendChat(FARMER_FLAG_LINES.KEEP_FLAG.line)
i++
}
3 -> {
animate(Animation(Animations.GNOME_FARMER_CLEAR_HOLES_8724))
farmerClear(dest)
}
4 -> {
unlock()
return true
}
}
return false
}
})
}
}
fun farmerClear(dest: Vinesweeper.SeedDestination) {
for(dx in -FARMER_CLEAR_RADIUS..FARMER_CLEAR_RADIUS) {
for(dy in -FARMER_CLEAR_RADIUS..FARMER_CLEAR_RADIUS) {
val toClear = getScenery(dest.loc.transform(dx, dy, 0))
if(toClear != null && intArrayOf(DEAD_PLANT_OBJ, *NUMBERS).contains(toClear.id)) {
if(toClear != null && intArrayOf(Sceneries.DEAD_PLANT_29456, *NUMBERS).contains(toClear.id)) {
SceneryBuilder.replace(toClear, toClear.transform(HOLES[0]))
}
}

View file

@ -7,6 +7,9 @@ import org.rs09.consts.Items
import rs09.game.content.dialogue.DialogueFile
import rs09.tools.END_DIALOGUE
abstract class FarmerDialogue : DialogueFile() {
companion object {
val BLINKIN_FLAG_LINES = arrayOf(
"Let me check for ya.",
"Flags? It appears ya don't have enough room for 'em. Make some space and talk to me again.",
@ -18,7 +21,6 @@ val BLINKIN_FLAG_LINES = arrayOf(
"Right y'are then! See ya.",
"It looks like ya got all the flags ya need right now. Ya don't need to buy any more."
)
val WINKIN_FLAG_LINES = arrayOf(
"Let me check for you.",
"I'm sorry dear, you don't appear to have enough room. Make some space and talk to me again.",
@ -30,8 +32,15 @@ val WINKIN_FLAG_LINES = arrayOf(
"Ok, dear. Goodbye.",
"It looks like you have all the flags you need. You don't need to buy any more."
)
abstract class FarmerDialogue : DialogueFile() {
enum class FARMER_FLAG_LINES(val line: String) {
FIND_FLAG("Ah, another flag to clear. Let's see what's there."),
FIND_SEED("Ah! A seed. Points for everyone near me!"),
NO_SEED("Hmm, no seeds planted here, I'm afraid."),
KEEP_FLAG("I'll have to keep this 'ere flag. Sorry."),
FIND_PLANT("Hmm. Looks like there's a plant here."),
DEAD_PLANT("Gracious me! This one's dead")
}
}
fun handleFlags(componentID: Int, buttonID: Int, lines: Array<String>) {
when(stage) {
20 -> npcl(lines[0]).also { stage++ }