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
}
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 ->
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.")
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
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)
}
}
SceneryBuilder.replace(scenery, scenery.transform(HOLES[0]))
farmerClear(dest)
return true
}
})
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 {
SceneryBuilder.replace(scenery, scenery.transform(HOLES[0]))
var i = 0
val lines = arrayOf("Hmm, no seeds planted here, I'm afraid.", "I'll have to keep this 'ere flag. Sorry.")
GameWorld.Pulser.submit(object : Pulse(3) {
override fun pulse(): Boolean {
sendChat(lines[i++])
return i >= lines.size
}
})
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 {
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
}
})
}
fun handleFarmerFlag(scenery: Scenery, dest: Vinesweeper.SeedDestination) {
val npc = this
lock()
var i = 0
animate(Animation(Animations.GNOME_FARMER_DIG_FLAG_8725))
GameWorld.Pulser.submit(object: Pulse(3) {
override fun pulse(): Boolean {
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,31 +7,40 @@ import org.rs09.consts.Items
import rs09.game.content.dialogue.DialogueFile
import rs09.tools.END_DIALOGUE
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.",
"Ah! First things first. One of the farm lads dropped off some flags for ya. Ya can have them back. Here ya go.",
"Righty-ho! Ya can have a total of 10 flags. To get yerself a full set of flags'll cost ya %d gold pieces. Would ya like to buy these flags?",
"Here ya go, then.",
"Flags? It appears ya don't have enough room for 'em. Make some space and talk to me again.",
"Ya don't have the coins fer these, I'm afraid! Come back when yer a little bit richer p'raps?",
"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.",
"Ah! First things first. One of the farmers dropped off some flags for you. You can have them back. Here you go.",
"Alright. You can have a total of 10 flags. To obtain a full set of flags will cost you %d coins. Would you like to buy these flags?",
"Here you are then, dear.",
"I'm sorry dear, you don't appear to have enough room. Make some space and talk to me again.",
"I'm afraid it looks like you don't have enough money, dear. Come back and see me again when you have a bit more.",
"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() {
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.",
"Ah! First things first. One of the farm lads dropped off some flags for ya. Ya can have them back. Here ya go.",
"Righty-ho! Ya can have a total of 10 flags. To get yerself a full set of flags'll cost ya %d gold pieces. Would ya like to buy these flags?",
"Here ya go, then.",
"Flags? It appears ya don't have enough room for 'em. Make some space and talk to me again.",
"Ya don't have the coins fer these, I'm afraid! Come back when yer a little bit richer p'raps?",
"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.",
"Ah! First things first. One of the farmers dropped off some flags for you. You can have them back. Here you go.",
"Alright. You can have a total of 10 flags. To obtain a full set of flags will cost you %d coins. Would you like to buy these flags?",
"Here you are then, dear.",
"I'm sorry dear, you don't appear to have enough room. Make some space and talk to me again.",
"I'm afraid it looks like you don't have enough money, dear. Come back and see me again when you have a bit more.",
"Ok, dear. Goodbye.",
"It looks like you have all the flags you need. You don't need to buy any more."
)
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++ }