mirror of
https://gitlab.com/2009scape/2009scape.git
synced 2026-08-24 03:45:13 -06:00
Incorporate changes from !2373
This commit is contained in:
parent
87e1b5e74c
commit
94fd11a07b
1 changed files with 99 additions and 65 deletions
|
|
@ -32,6 +32,8 @@ import core.game.system.task.Pulse
|
|||
import core.game.world.GameWorld
|
||||
import core.game.world.GameWorld.ticks
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.map.Region
|
||||
import core.game.world.map.RegionChunk
|
||||
import core.game.world.map.RegionManager
|
||||
import core.game.world.map.zone.ZoneBorders
|
||||
import core.game.world.update.flag.context.Animation
|
||||
|
|
@ -50,27 +52,26 @@ class Vinesweeper : InteractionListener, InterfaceListener, MapArea {
|
|||
}
|
||||
|
||||
override fun areaEnter(entity: Entity) {
|
||||
if(entity is Player)
|
||||
{
|
||||
if (entity is Player) {
|
||||
openOverlay(entity, Components.RABBIT_OVERLAY_689)
|
||||
sendUpdatedPoints(entity)
|
||||
}
|
||||
}
|
||||
|
||||
override fun areaLeave(entity: Entity, logout: Boolean) {
|
||||
if(entity is Player) {
|
||||
if (entity is Player) {
|
||||
entity.interfaceManager.closeOverlay()
|
||||
if(!logout) {
|
||||
if (!logout) {
|
||||
sendMessage(entity, "Winkin's Farm thanks you for your visit.")
|
||||
sendMessage(entity, "Leftover ogleroots and flags have been returned to the establishment.")
|
||||
sendMessage(entity, "You have been reimbursed at a rate of 10gp per ogleroot and the flags have been collected.")
|
||||
val flags = entity.inventory.getAmount(Item(Items.FLAG_12625))
|
||||
if(flags > 0) {
|
||||
if (flags > 0) {
|
||||
entity.setAttribute("/save:vinesweeper:stored-flags", flags)
|
||||
entity.inventory.remove(Item(Items.FLAG_12625, flags))
|
||||
}
|
||||
val roots = entity.inventory.getAmount(Item(Items.OGLEROOT_12624))
|
||||
if(roots > 0) {
|
||||
if (roots > 0) {
|
||||
entity.inventory.remove(Item(Items.OGLEROOT_12624, roots))
|
||||
entity.inventory.add(Item(Items.COINS_995, roots * 10))
|
||||
}
|
||||
|
|
@ -96,7 +97,7 @@ class Vinesweeper : InteractionListener, InterfaceListener, MapArea {
|
|||
return@on true
|
||||
}
|
||||
on(HOLES, IntType.SCENERY, "dig") { player, node ->
|
||||
if(!player.inventory.contains(Items.SPADE_952, 1)) {
|
||||
if (!player.inventory.contains(Items.SPADE_952, 1)) {
|
||||
// TODO (crash): authenticity
|
||||
player.sendMessage("You need a spade to dig here.")
|
||||
} else {
|
||||
|
|
@ -113,7 +114,7 @@ class Vinesweeper : InteractionListener, InterfaceListener, MapArea {
|
|||
on(HOLES, IntType.SCENERY, "flag") { player, node ->
|
||||
val hole = node as Scenery
|
||||
var count = 0
|
||||
if(player.location != node.location) {
|
||||
if (player.location != node.location) {
|
||||
plantFlag(player,hole)
|
||||
return@on true
|
||||
}
|
||||
|
|
@ -149,7 +150,7 @@ class Vinesweeper : InteractionListener, InterfaceListener, MapArea {
|
|||
1 -> "You get some mud in your eye and it stings! You have no idea what is in the hole."
|
||||
2 -> "The mud seems to be too thick to see what is there."
|
||||
3 -> "A slimy worm wriggles out of the mud, making you jump and lose concentration. You're not sure if there is a seed here or not."
|
||||
else -> if(isSeed(node.location)) {
|
||||
else -> if (isSeed(node.location)) {
|
||||
"You notice a seed hidden in the dirt."
|
||||
} else {
|
||||
"You are certain there is no seed planted here."
|
||||
|
|
@ -260,7 +261,7 @@ class Vinesweeper : InteractionListener, InterfaceListener, MapArea {
|
|||
|
||||
data class SeedDestination(val player: Player, val loc: Location, val alive: Boolean) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
return if(other is SeedDestination) {
|
||||
return if (other is SeedDestination) {
|
||||
loc == other.loc
|
||||
} else {
|
||||
false
|
||||
|
|
@ -272,8 +273,7 @@ class Vinesweeper : InteractionListener, InterfaceListener, MapArea {
|
|||
}
|
||||
}
|
||||
|
||||
companion object
|
||||
{
|
||||
companion object {
|
||||
val AVACH_NIMPORTO_LOC = Location.create(1637, 4709)
|
||||
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)
|
||||
|
|
@ -332,9 +332,9 @@ class Vinesweeper : InteractionListener, InterfaceListener, MapArea {
|
|||
val reward = REWARDS[buttonID] ?: return
|
||||
val cost = amount * reward.points
|
||||
val points = player.getAttribute("vinesweeper:points", 0)
|
||||
if(cost in 1 until points) {
|
||||
if (cost in 1 until points) {
|
||||
val item = Item(reward.itemID, amount)
|
||||
if(!player.inventory.add(item)) {
|
||||
if (!player.inventory.add(item)) {
|
||||
GroundItemManager.create(item, player)
|
||||
}
|
||||
player.incrementAttribute("/save:vinesweeper:points", -cost)
|
||||
|
|
@ -345,7 +345,6 @@ class Vinesweeper : InteractionListener, InterfaceListener, MapArea {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
val TUTORIAL = 685
|
||||
|
||||
val INSTRUCTION_SIGNS = hashMapOf(
|
||||
|
|
@ -360,52 +359,87 @@ class Vinesweeper : InteractionListener, InterfaceListener, MapArea {
|
|||
|
||||
val MAX_SEEDS = 300
|
||||
val FARMER_CLEAR_RADIUS = 3
|
||||
val VINESWEEPER_BORDERS = ZoneBorders(1600,4672,1663,4735)
|
||||
val VINESWEEPER_REGION = RegionManager.forId(6473)
|
||||
var SEED_LOCS: HashSet<Location> = HashSet()
|
||||
|
||||
fun sendUpdatedPoints(player: Player) {
|
||||
val points = player.getAttribute("vinesweeper:points", 0)
|
||||
setVarbit(player, 4449, points)
|
||||
}
|
||||
|
||||
var SEED_LOCS: HashSet<Location> = HashSet()
|
||||
|
||||
fun isSeed(loc: Location): Boolean {
|
||||
val scenery = getScenery(loc)
|
||||
return scenery != null && SEED_LOCS.contains(scenery.location)
|
||||
}
|
||||
|
||||
fun populateSeeds() {
|
||||
val holes = countHoles()
|
||||
val seeds = min(1.0 * MAX_SEEDS, holes * 0.13).toInt()
|
||||
var tries = 0 // Prevent the while loop from crashing the server
|
||||
while(SEED_LOCS.size < seeds && tries++ < 1000) {
|
||||
val loc = VINESWEEPER_BORDERS.getRandomLoc()
|
||||
val scenery = getScenery(loc)
|
||||
if(scenery != null && HOLES.contains(scenery.id)) {
|
||||
SEED_LOCS.add(loc)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun countHoles(): Int {
|
||||
val northEastX = VINESWEEPER_BORDERS.northEastX
|
||||
val northEastY = VINESWEEPER_BORDERS.northEastY
|
||||
val southWestX = VINESWEEPER_BORDERS.southWestX
|
||||
val southWestY = VINESWEEPER_BORDERS.southWestY
|
||||
var holeCount = 0
|
||||
for (x in southWestX .. northEastX){
|
||||
for (y in southWestY .. northEastY){
|
||||
val scenery = getScenery(x, y, 0)
|
||||
if(scenery != null && HOLES.contains(scenery.id)) {
|
||||
holeCount++
|
||||
fun resetChunkIfBarren(chunk: RegionChunk) {
|
||||
val wipedHoles = ArrayList<Scenery>()
|
||||
for (i in 0 until chunk.objects.size) {
|
||||
for (x in 0 until 8) {
|
||||
for (y in 0 until 8) {
|
||||
val obj = chunk.objects[i][x][y] ?: continue
|
||||
if (obj.id in HOLES) {
|
||||
return //this chunk is not barren and hence should not be reset
|
||||
}
|
||||
if (obj.id == NUMBERS[0]) {
|
||||
wipedHoles.add(obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return holeCount
|
||||
for (scenery in wipedHoles) {
|
||||
SceneryBuilder.replace(scenery, scenery.transform(HOLES[0]))
|
||||
}
|
||||
}
|
||||
|
||||
fun countFieldState(chunk: RegionChunk, emptyHoleList: ArrayList<Scenery>, seedHoleList: ArrayList<Scenery>) {
|
||||
for (i in 0 until chunk.objects.size) {
|
||||
for (x in 0 until 8) {
|
||||
for (y in 0 until 8) {
|
||||
val obj = chunk.objects[i][x][y] ?: continue
|
||||
if (obj.id in HOLES) {
|
||||
if (obj.location in SEED_LOCS) {
|
||||
seedHoleList.add(obj)
|
||||
} else {
|
||||
emptyHoleList.add(obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun populateSeeds() {
|
||||
// First, see if there are any chunks that have been completely wiped out. These need to be restored first (GL #2400).
|
||||
Region.load(VINESWEEPER_REGION)
|
||||
for (cx in 0 until 8) {
|
||||
for (cy in 0 until 8) {
|
||||
val chunk = VINESWEEPER_REGION.chunks[cx][cy][0]
|
||||
resetChunkIfBarren(chunk)
|
||||
}
|
||||
}
|
||||
// Next, get the state of the field
|
||||
val emptyHoleList = ArrayList<Scenery>()
|
||||
val seedHoleList = ArrayList<Scenery>()
|
||||
for (cx in 0 until 8) {
|
||||
for (cy in 0 until 8) {
|
||||
val chunk = VINESWEEPER_REGION.chunks[cx][cy][0]
|
||||
countFieldState(chunk, emptyHoleList, seedHoleList)
|
||||
}
|
||||
}
|
||||
val target = min(1.0 * MAX_SEEDS, (seedHoleList.size + emptyHoleList.size) * 0.13).toInt()
|
||||
val seedsToAdd = target - seedHoleList.size
|
||||
if (seedsToAdd < 1) {
|
||||
return
|
||||
}
|
||||
emptyHoleList.shuffle()
|
||||
for (i in 0 until seedsToAdd) {
|
||||
SEED_LOCS.add(emptyHoleList[i].location)
|
||||
}
|
||||
}
|
||||
|
||||
fun plantFlag(player: Player, hole: Scenery) {
|
||||
if(player.inventory.remove(Item(Items.FLAG_12625, 1))) {
|
||||
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.")
|
||||
|
|
@ -425,9 +459,9 @@ class Vinesweeper : InteractionListener, InterfaceListener, MapArea {
|
|||
|
||||
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))) {
|
||||
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!")
|
||||
|
|
@ -447,36 +481,36 @@ class Vinesweeper : InteractionListener, InterfaceListener, MapArea {
|
|||
}
|
||||
|
||||
fun dig(player: Player, loc: Location) {
|
||||
if(isSeed(loc)) {
|
||||
if (isSeed(loc)) {
|
||||
val oldPoints = player.getAttribute("vinesweeper:points", 0)
|
||||
player.setAttribute("/save:vinesweeper:points", Math.max(oldPoints-10, 0))
|
||||
sendUpdatedPoints(player)
|
||||
player.sendMessage("Oh dear! It looks like you dug up a potato seed by mistake.")
|
||||
scheduleNPCs(player, loc, false, false)
|
||||
val scenery = getScenery(loc)
|
||||
if(scenery != null) {
|
||||
if (scenery != null) {
|
||||
SceneryBuilder.replace(scenery, scenery.transform(Sceneries.DEAD_PLANT_29456))
|
||||
}
|
||||
} else {
|
||||
player.incrementAttribute("/save:vinesweeper:points", 1)
|
||||
sendUpdatedPoints(player)
|
||||
var count = 0
|
||||
for(dx in -1..1) {
|
||||
for(dy in -1..1) {
|
||||
if(isSeed(loc.transform(dx, dy, 0))) {
|
||||
for (dx in -1..1) {
|
||||
for (dy in -1..1) {
|
||||
if (isSeed(loc.transform(dx, dy, 0))) {
|
||||
count += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
val scenery = getScenery(loc)
|
||||
if(scenery != null) {
|
||||
if (scenery != null) {
|
||||
SceneryBuilder.replace(scenery, scenery.transform(NUMBERS[count]))
|
||||
}
|
||||
if(count == 0) {
|
||||
for(dx in -1..1) {
|
||||
for(dy in -1..1) {
|
||||
if (count == 0) {
|
||||
for (dx in -1..1) {
|
||||
for (dy in -1..1) {
|
||||
val newLoc = loc.transform(dx, dy, 0)
|
||||
if(isHole(newLoc))
|
||||
if (isHole(newLoc))
|
||||
dig(player, newLoc)
|
||||
}
|
||||
}
|
||||
|
|
@ -505,9 +539,9 @@ 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) { RABBITS + FARMERS } else { FARMERS }
|
||||
for(npc in findLocalNPCs(player, ids, 30)) {
|
||||
if(npc is VinesweeperNPC) {
|
||||
val ids = if (rabbit) { RABBITS + FARMERS } else { FARMERS }
|
||||
for (npc in findLocalNPCs(player, ids, 30)) {
|
||||
if (npc is VinesweeperNPC) {
|
||||
npc.seedDestinations.add(dest)
|
||||
npc.resetWalk()
|
||||
}
|
||||
|
|
@ -599,7 +633,7 @@ class VinesweeperNPC : AbstractNPC {
|
|||
}
|
||||
|
||||
override fun getMovementDestination(): Location? {
|
||||
if(seedDestinations.size > 0) {
|
||||
if (seedDestinations.size > 0) {
|
||||
seedDestinations.sortBy { a -> a.loc.getDistance(location).toInt() }
|
||||
return seedDestinations.first().loc
|
||||
} else {
|
||||
|
|
@ -608,7 +642,7 @@ class VinesweeperNPC : AbstractNPC {
|
|||
}
|
||||
|
||||
fun handleRabbitSeed(scenery: Scenery, dest: Vinesweeper.SeedDestination) {
|
||||
if(SEED_LOCS.contains(dest.loc)) {
|
||||
if (SEED_LOCS.contains(dest.loc)) {
|
||||
val replacement = Sceneries.DEAD_PLANT_29456
|
||||
lock(4)
|
||||
animate(Animation(Animations.RABBIT_EAT_SEED_8718))
|
||||
|
|
@ -688,10 +722,10 @@ class VinesweeperNPC : AbstractNPC {
|
|||
}
|
||||
|
||||
fun farmerClear(dest: Vinesweeper.SeedDestination) {
|
||||
for(dx in -FARMER_CLEAR_RADIUS..FARMER_CLEAR_RADIUS) {
|
||||
for(dy in -FARMER_CLEAR_RADIUS..FARMER_CLEAR_RADIUS) {
|
||||
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(Sceneries.DEAD_PLANT_29456, *NUMBERS).contains(toClear.id)) {
|
||||
if (toClear != null && intArrayOf(Sceneries.DEAD_PLANT_29456, *NUMBERS).contains(toClear.id)) {
|
||||
SceneryBuilder.replace(toClear, toClear.transform(HOLES[0]))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue