Merge branch 'MobyDick2' into 'master'

Fixed parlor chairs, removed RegionPlane and Viewport, ported Location to Kotlin (credit: Oven Bread), added message when running away from evil chicken (credit: Oven Bread), and fixed the vinesweeper field running dry

Closes #2193, #2619, and #2628

See merge request 2009scape/2009scape!2369
This commit is contained in:
Player Name 2026-08-01 02:38:31 +00:00
commit f2f8d7a7e6
199 changed files with 3314 additions and 4742 deletions

View file

@ -1,7 +1,7 @@
variables:
# This will suppress any download for dependencies and plugins or upload messages which would clutter the console log.
# `showDateTime` will show the passed time in milliseconds. You need to specify `--batch-mode` to make this work.
MAVEN_OPTS: "-Dhttps.protocols=TLSv1.2 -Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true -Xmx3g"
MAVEN_OPTS: "-Dhttps.protocols=TLSv1.2 -Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true -Xmx4g -Xms2g"
# As of Maven 3.3.0 instead of this you may define these options in `.mvn/maven.config` so the same config is used
# when running from the command line.
MAVEN_CLI_OPTS: "--batch-mode --errors --fail-fast --show-version"

View file

@ -1,27 +0,0 @@
<parsing>
<ObjectAction mode="add" id="1814" x="3090" y="3475" z="0" type="4" direction="nw"/>
<ObjectAction mode="add" id="2646" x="2445" y="3413" z="0" direction="nw"/>
<ObjectAction mode="add" id="2646" x="2447" y="3414" z="0" direction="e"/>
<ObjectAction mode="add" id="2646" x="2447" y="3421" z="0" direction="nw"/>
<ObjectAction mode="remove" id="37670" x="3292" y="3299" z="0"/>
<ObjectAction mode="add" id="37304" x="3292" y="3299" z="0"/>
<ObjectAction mode="add" id="20987" x="3821" y="2996" z="0"/>
<ObjectAction mode="remove" id="356" x="2804" y="3428" z="0"/>
<ObjectAction mode="add" id="356" x="2804" y="3428" z="0"/>
<ObjectAction mode="remove" id="20228" x="2537" y="3573" z="0"/>
<ObjectAction mode="add" id="27663" x="2537" y="3573" z="0" direction="w"/>
<ObjectAction mode="add" id="39237" x="2957" y="3266" z="0" direction="n"/>
<ObjectAction mode="add" id="39245" x="2956" y="3270" z="0" direction="se"/>
<ObjectAction mode="add" id="39242" x="2955" y="3273" z="0" direction="w"/>
<ObjectAction mode="add" id="39241" x="2955" y="3274" z="0" />
<ObjectAction mode="add" id="20987" x="2821" y="2996" z="0" direction="s"/>
<ObjectAction mode="add" id="21301" x="2662" y="3162" z="0" direction="e"/>
<ObjectAction mode="add" id="4176" x="2629" y="3661" z="2" type="4" direction="e"/>
</parsing>

View file

@ -0,0 +1,165 @@
[
{
"mode": "add",
"id": "1814",
"location": "3090, 3475, 0",
"type": "4",
"direction": "nw"
},
{
"mode": "add",
"id": "2646",
"location": "2445, 3413, 0",
"direction": "nw"
},
{
"mode": "add",
"id": "2646",
"location": "2447, 3414, 0",
"direction": "e"
},
{
"mode": "add",
"id": "2646",
"location": "2447, 3421, 0",
"direction": "nw"
},
{
"comment": "Prison Pete Random",
"mode": "add",
"id": "36788",
"location": "2094, 4465, 0",
"type": "10",
"direction": "e"
},
{
"comment": "Green Portal",
"mode": "remove",
"id": "11371",
"location": "2085, 4457, 0"
},
{
"comment": "Lever",
"mode": "remove",
"id": "10817",
"location": "2083, 4460, 0"
},
{
"comment": "Lever",
"mode": "add",
"id": "26191",
"location": "2083, 4460, 0",
"type": "10",
"direction": "e"
},
{
"comment": "Window",
"mode": "add",
"id": "26184",
"location": "2084, 4459, 0",
"type": "0",
"direction": "n"
},
{
"comment": "Door",
"mode": "add",
"id": "26186",
"location": "2085, 4459, 0",
"type": "0",
"direction": "n"
},
{
"comment": "Door",
"mode": "add",
"id": "26188",
"location": "2086, 4459, 0",
"type": "0",
"direction": "n"
},
{
"comment": "Window",
"mode": "add",
"id": "26184",
"location": "2087, 4459, 0",
"type": "0",
"direction": "n"
},
{
"mode": "remove",
"id": "37670",
"location": "3292, 3299, 0"
},
{
"mode": "add",
"id": "37304",
"location": "3292, 3299, 0"
},
{
"mode": "add",
"id": "20987",
"location": "3821, 2996, 0"
},
{
"mode": "remove",
"id": "356",
"location": "2804, 3428, 0"
},
{
"mode": "add",
"id": "356",
"location": "2804, 3428, 0"
},
{
"mode": "remove",
"id": "20228",
"location": "2537, 3573, 0"
},
{
"mode": "add",
"id": "27663",
"location": "2537, 3573, 0",
"direction": "w"
},
{
"mode": "add",
"id": "39237",
"location": "2957, 3266, 0",
"direction": "n"
},
{
"mode": "add",
"id": "39245",
"location": "2956, 3270, 0",
"direction": "se"
},
{
"mode": "add",
"id": "39242",
"location": "2955, 3273, 0",
"direction": "w"
},
{
"mode": "add",
"id": "39241",
"location": "2955, 3274, 0"
},
{
"mode": "add",
"id": "20987",
"location": "2821, 2996, 0",
"direction": "s"
},
{
"mode": "add",
"id": "21301",
"location": "2662, 3162, 0",
"direction": "e"
},
{
"mode": "add",
"id": "4176",
"location": "2629, 3661, 2",
"type": "4",
"direction": "e"
}
]

View file

@ -252,6 +252,7 @@
<configuration>
<useFile>false</useFile>
<trimStackTrace>false</trimStackTrace>
<argLine>-Xmx4g -Xms2g</argLine>
</configuration>
<version>2.22.0</version>
</plugin>

View file

@ -99,12 +99,18 @@ class ShootingStar(var level: ShootingStarType = ShootingStarType.values().rando
return ShootingStarType.values()[level.ordinal - 1]
}
/**
* Clears the current star object or sprite
*/
fun clear() {
SceneryBuilder.remove(starObject)
clearSprite()
}
/**
* Fires the shooting star (spawns a new one). Only used when spawning new shooting stars, not for downgrading existing ones.
*/
fun fire() {
SceneryBuilder.remove(starObject)
clearSprite()
SceneryBuilder.add(starObject)
if(!isSpawned) {
(0..2).forEach {

View file

@ -17,6 +17,7 @@ import core.game.world.GameWorld
import core.tools.Log
import core.tools.secondsToTicks
import content.data.Quests
import core.game.node.scenery.SceneryBuilder
class ShootingStarPlugin : LoginListener, InteractionListener, TickListener, Commands, StartupListener {
override fun login(player: Player) {
@ -46,6 +47,7 @@ class ShootingStarPlugin : LoginListener, InteractionListener, TickListener, Com
// Check if it's time to fire a new one
if (star.ticks >= tickDelay && !star.spriteSpawned) {
star.clear()
star.rebuildVars()
star.fire()
}
@ -138,6 +140,7 @@ class ShootingStarPlugin : LoginListener, InteractionListener, TickListener, Com
}
define("submit", Privilege.ADMIN, description = "Rebuilds and fires the shooting star event immediately.") { _, _ ->
star.clear()
star.rebuildVars()
star.fire()
}

View file

@ -8,12 +8,14 @@ import core.game.node.item.Item
import core.tools.RandomFunction
import org.rs09.consts.Items
import content.global.ame.RandomEventNPC
import core.api.sendMessage
import core.api.utils.WeightBasedTable
val ids = (2463..2468).toList()
class EvilChickenNPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(2463) {
val phrases = arrayOf("Bwuk","Bwuk bwuk bwuk","Flee from me, @name!","Begone, @name!","Bwaaaauuuk bwuk bwuk","MUAHAHAHAHAAA!")
var sentMessage = false
override fun talkTo(npc: NPC) {}
override fun init() {
@ -31,13 +33,16 @@ class EvilChickenNPC(override var loot: WeightBasedTable? = null) : RandomEventN
}
override fun tick() {
if(!player.location.withinDistance(this.location,8)){
this.terminate()
}
if(getWorldTicks() % 10 == 0){
sendChat(phrases.random().replace("@name",player.username.capitalize()))
if (!sentMessage) {
if (!player.location.withinDistance(this.location, 8)) {
// https://www.youtube.com/watch?v=v9p_I_Tq3JE
sendMessage(player, "The Evil Chicken realises you're out of range and vanishes.")
sentMessage = true
terminate()
} else if (getWorldTicks() % 10 == 0) {
sendChat(phrases.random().replace("@name", player.username.capitalize()))
}
}
super.tick()
if(!player.viewport.currentPlane.npcs.contains(this)) this.clear()
}
}

View file

@ -12,8 +12,6 @@ import core.game.interaction.InteractionListener
import core.game.interaction.QueueStrength
import core.game.node.entity.Entity
import core.game.node.entity.player.Player
import core.game.system.task.Pulse
import core.game.world.GameWorld.Pulser
import core.game.world.map.Location
import core.game.world.map.zone.ZoneBorders
import core.game.world.map.zone.ZoneRestriction
@ -109,73 +107,17 @@ class MazeInterface : InteractionListener, EventHook<TickEvent>, MapArea {
addItemOrDrop(player, REWARD_ITEM[randomNumber], itemQuantity.toInt())
}
}
/**
* Chest Location to rotation mapping.
* This is needed as it is impossible to obtain the underlying chest scenery for the rotation.
* 0: Facing North, 1: Facing East, 2: Facing South, 3: Facing West
*/
val chestLocationRotationMap = mapOf(
Location(2930, 4595, 0).toString() to 2,
Location(2924, 4572, 0).toString() to 2,
Location(2925, 4573, 0).toString() to 0,
Location(2900, 4578, 0).toString() to 2,
Location(2901, 4560, 0).toString() to 1,
Location(2890, 4599, 0).toString() to 2,
Location(2896, 4591, 0).toString() to 2,
Location(2895, 4592, 0).toString() to 1,
Location(2901, 4560, 0).toString() to 3,
Location(2918, 4590, 0).toString() to 1,
Location(2917, 4590, 0).toString() to 3,
)
/**
* Chest Interaction workaround
*
* The issue here is that the walls(3626) of the Maze are overlapping some(not all) chest sceneries.
*
* The types for the wallScenery:
* Type 0 - flat panel |
* Type 2 - right angle panel with rotation 0:r 1:7 2:> 3:L
* Type 3 - corner post . for angle edges of walls
*/
fun overrideScenery(wallScenery: core.game.node.scenery.Scenery, chestSceneryId: Int): core.game.node.scenery.Scenery {
if (wallScenery.id == chestSceneryId) {
replaceScenery(wallScenery, Scenery.CHEST_3636, 30)
wallScenery.isActive = true
return wallScenery // Return the chest scenery as the wallScenery isn't there.
}
addScenery(Scenery.CHEST_3636, wallScenery.location, chestLocationRotationMap[wallScenery.location.toString()] ?: 0, 10)
addScenery(wallScenery)
// replaceScenery(newChestScenery, Scenery.CHEST_3636, 3) // didn't work for an underlying scenery
// I did a world pulse since everyone will get to see the chest open.
Pulser.submit(object : Pulse(30) {
override fun pulse(): Boolean {
addScenery(Scenery.CHEST_3635, wallScenery.location, chestLocationRotationMap[wallScenery.location.toString()] ?: 0, 10)
addScenery(wallScenery)
return true
}
})
// Return the chest scenery to replace PacketProcessor so that MISMATCH will not happen.
return core.game.node.scenery.Scenery(
chestSceneryId,
wallScenery.location,
chestLocationRotationMap[wallScenery.location.toString()] ?: 0
)
}
}
override fun defineListeners() {
// This somehow doesn't trigger as the scenery.id != objId (3626 != 3635)
on(Scenery.CHEST_3635, IntType.SCENERY, "open") { player, node ->
lock(player, 3)
animate(player, 536)
replaceScenery(node.asScenery(), Scenery.CHEST_3636, 3)
if (getAttribute(player, MAZE_ATTRIBUTE_TICKS_LEFT, 0) > 0 && getAttribute(player, MAZE_ATTRIBUTE_CHESTS_OPEN, 0) < 10) {
animate(player, 536)
// val actualScenery = RegionManager.getObject(node.location.z, node.location.x, node.location.y, 3626)
val tableRoll = CHEST_REWARDS.roll()
addItemOrBank(player, tableRoll[0].id, tableRoll[0].amount)
when (tableRoll[0].id){
when (tableRoll[0].id) {
Items.AIR_RUNE_556 -> sendItemDialogue(player, Items.AIR_RUNE_556, "You've found some air runes!")
Items.WATER_RUNE_555 -> sendItemDialogue(player, Items.WATER_RUNE_555, "You've found some water runes!")
Items.EARTH_RUNE_557 -> sendItemDialogue(player, Items.EARTH_RUNE_557, "You've found some earth runes!")
@ -187,7 +129,7 @@ class MazeInterface : InteractionListener, EventHook<TickEvent>, MapArea {
Items.STRENGTH_POTION2_117 -> sendItemDialogue(player, Items.STRENGTH_POTION2_117, "You've found a strength potion!")
Items.DEFENCE_POTION2_135 -> sendItemDialogue(player, Items.DEFENCE_POTION2_135, "You've found a defence potion!")
}
setAttribute(player, MAZE_ATTRIBUTE_CHESTS_OPEN, getAttribute(player, MAZE_ATTRIBUTE_CHESTS_OPEN, 0))
setAttribute(player, MAZE_ATTRIBUTE_CHESTS_OPEN, getAttribute(player, MAZE_ATTRIBUTE_CHESTS_OPEN, 0) + 1)
} else {
sendMessage(player,"You find nothing of interest.")
}

View file

@ -4,6 +4,7 @@ import core.game.node.entity.Entity
import core.game.node.entity.npc.NPC
import content.global.ame.RandomEventNPC
import core.api.utils.WeightBasedTable
import core.game.world.map.MapDistance
val ids = (391..396).toList()
@ -21,10 +22,12 @@ class RiverTrollRENPC(override var loot: WeightBasedTable? = null) : RandomEvent
super.finalizeDeath(killer)
}
override fun tick() {
if(!player.location.withinDistance(this.location,8)){
if (!player.location.withinDistance(this.location, 8)) {
this.terminate()
}
super.tick()
if(!player.viewport.currentPlane.npcs.contains(this)) this.clear()
if (!player.location.withinDistance(this.location, MapDistance.RENDERING.distance)) {
this.clear()
}
}
}

View file

@ -4,6 +4,7 @@ import core.game.node.entity.Entity
import core.game.node.entity.npc.NPC
import content.global.ame.RandomEventNPC
import core.api.utils.WeightBasedTable
import core.game.world.map.MapDistance
val ids = (413..418).toList()
@ -21,10 +22,12 @@ class RockGolemRENPC(override var loot: WeightBasedTable? = null) : RandomEventN
super.finalizeDeath(killer)
}
override fun tick() {
if(!player.location.withinDistance(this.location,8)){
if (!player.location.withinDistance(this.location, 8)) {
this.terminate()
}
super.tick()
if(!player.viewport.currentPlane.npcs.contains(this)) this.clear()
if (!player.location.withinDistance(this.location, MapDistance.RENDERING.distance)) {
this.clear()
}
}
}

View file

@ -4,6 +4,7 @@ import core.game.node.entity.Entity
import core.game.node.entity.npc.NPC
import content.global.ame.RandomEventNPC
import core.api.utils.WeightBasedTable
import core.game.world.map.MapDistance
class ShadeRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(425){
val ids = (425..430).toList()
@ -20,10 +21,12 @@ class ShadeRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(4
super.finalizeDeath(killer)
}
override fun tick() {
if(!player.location.withinDistance(this.location,8)){
if (!player.location.withinDistance(this.location, 8)) {
this.terminate()
}
super.tick()
if(!player.viewport.currentPlane.npcs.contains(this)) this.clear()
if (!player.location.withinDistance(this.location, MapDistance.RENDERING.distance)) {
this.clear()
}
}
}

View file

@ -4,6 +4,7 @@ import core.game.node.entity.Entity
import core.game.node.entity.npc.NPC
import content.global.ame.RandomEventNPC
import core.api.utils.WeightBasedTable
import core.game.world.map.MapDistance
val ids = (438..443).toList()
@ -21,10 +22,12 @@ class TreeSpiritRENPC(override var loot: WeightBasedTable? = null) : RandomEvent
super.finalizeDeath(killer)
}
override fun tick() {
if(!player.location.withinDistance(this.location,8)){
if (!player.location.withinDistance(this.location, 8)) {
this.terminate()
}
super.tick()
if(!player.viewport.currentPlane.npcs.contains(this)) this.clear()
if (!player.location.withinDistance(this.location, MapDistance.RENDERING.distance)) {
this.clear()
}
}
}

View file

@ -4,6 +4,7 @@ import core.game.node.entity.Entity
import core.game.node.entity.npc.NPC
import content.global.ame.RandomEventNPC
import core.api.utils.WeightBasedTable
import core.game.world.map.MapDistance
class ZombieRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(419){
val ids = (419..424).toList()
@ -20,10 +21,12 @@ class ZombieRENPC(override var loot: WeightBasedTable? = null) : RandomEventNPC(
super.finalizeDeath(killer)
}
override fun tick() {
if(!player.location.withinDistance(this.location,8)){
if (!player.location.withinDistance(this.location, 8)) {
this.terminate()
}
super.tick()
if(!player.viewport.currentPlane.npcs.contains(this)) this.clear()
if (!player.location.withinDistance(this.location, MapDistance.RENDERING.distance)) {
this.clear()
}
}
}

View file

@ -11,24 +11,20 @@ import core.game.world.GameWorld
import core.game.world.map.Location
import core.game.world.map.RegionManager
import core.game.world.map.zone.ZoneBorders
import core.game.world.update.flag.*
import org.json.simple.JSONArray
import org.json.simple.JSONObject
import core.ServerConstants
import core.api.log
import core.game.bots.AIRepository
import core.game.bots.CombatBotAssembler
import core.game.bots.Script
import core.game.interaction.IntType
import core.game.interaction.InteractionListeners
import core.tools.Log
import java.io.File
import java.io.FileReader
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import kotlin.random.Random
/**
* A bot script for Adventurers who explore the world!
* @param counter used in the bots random idling function.
@ -114,7 +110,7 @@ class Adventurer(val style: CombatStyle): Script() {
}
private fun otherPlayersNearby(): Boolean {
val localPlayers = RegionManager.getLocalPlayers(bot)
val localPlayers = RegionManager.getLocalPlayers(bot.location)
val otherPlayers = localPlayers.filter { it.name != bot.name }
return otherPlayers.isNotEmpty()
}
@ -503,7 +499,7 @@ class Adventurer(val style: CombatStyle): Script() {
dateCode == 404 -> lineAlt = dialogue.getLines("easter").rand()
}
var localPlayers = RegionManager.getLocalPlayers(bot)
val localPlayers = RegionManager.getLocalPlayers(bot.location)
if (localPlayers.isNotEmpty()) {
val localPlayer = localPlayers
.filter { it.name != bot.name }

View file

@ -58,7 +58,7 @@ class CannonballSmelter : Script() {
} else if(!coalMine.insideBorder(bot)){
scriptAPI.walkTo(coalMine.randomLoc)
} else {
val rock = scriptAPI.getNearestObjectByPredicate({node -> node?.name?.equals("rocks", true)!! && MiningNode.forId(node?.id!!).reward == Items.COAL_453 })
val rock = scriptAPI.getNearestObjectByPredicate { node -> node?.name?.equals("rocks", true)!! && MiningNode.forId(node.id)?.reward == Items.COAL_453 }
if(rock != null) {
scriptAPI.interact(bot, rock, "mine")
} else {
@ -75,7 +75,7 @@ class CannonballSmelter : Script() {
var loc = ironMine.randomLoc
scriptAPI.walkTo(loc)
} else {
val rock = scriptAPI.getNearestObjectByPredicate({node -> node?.name?.equals("rocks", true)!! && MiningNode.forId(node?.id!!).reward == Items.IRON_ORE_440 })
val rock = scriptAPI.getNearestObjectByPredicate { node -> node?.name?.equals("rocks", true)!! && MiningNode.forId(node.id)?.reward == Items.IRON_ORE_440 }
//rock?.let { InteractionListeners.run(rock.id, IntType.SCENERY,"mine",bot,rock) }
if(rock != null) {
scriptAPI.interact(bot, rock, "mine")

View file

@ -262,10 +262,12 @@ class DoublingMoney : Script() {
minDist = min(minDist, loc.getDistance(bot.location))
}
if (minDist > 1) return 2
RegionManager.forId(bot.location.regionId).planes[bot.location.z].players.forEach {
if (AIRepository.PulseRepository[it?.username?.lowercase()]?.botScript is DoublingMoney
&& it != bot
&& it.location.getDistance(bot.location) <= 1) {
val region = RegionManager.forId(bot.location.regionId)
val players = region.assemblePlayerList(bot.location.z)
for (player in players) {
if (AIRepository.PulseRepository[player.username.lowercase()]?.botScript is DoublingMoney
&& player != bot
&& player.location.getDistance(bot.location) <= 1) {
return 2
}
}

View file

@ -79,7 +79,7 @@ public final class ChainhitSpecialHandler extends RangeSwingHandler implements P
if (!((Player) entity).getSettings().drainSpecial(SPECIAL_ENERGY)) {
return -1;
}
state.setStyle(CombatStyle.RANGE);
state.setStyle(CombatStyle.RANGE);
if (victim instanceof NPC) {
NPC npc = victim.asNpc();
if (npc.getId() == 2440) {
@ -186,9 +186,9 @@ public final class ChainhitSpecialHandler extends RangeSwingHandler implements P
if (list == null) {
int distance = 5;
if (victim instanceof NPC) {
e.setAttribute("chain-hit_v", list = RegionManager.getLocalNpcs(e, distance));
e.setAttribute("chain-hit_v", list = RegionManager.getLocalNPCs(e.getLocation(), distance));
} else {
e.setAttribute("chain-hit_v", list = RegionManager.getLocalPlayers(e, distance));
e.setAttribute("chain-hit_v", list = RegionManager.getLocalPlayers(e.getLocation(), distance));
}
list.remove(e);
list.remove(victim);

View file

@ -6,16 +6,15 @@ import core.game.node.entity.combat.equipment.Ammunition;
import core.game.node.entity.combat.equipment.RangeWeapon;
import core.game.node.entity.combat.equipment.Weapon;
import core.game.node.entity.combat.equipment.WeaponInterface;
import core.game.node.entity.npc.NPC;
import core.game.node.entity.player.Player;
import core.game.node.entity.skill.Skills;
import core.game.world.map.RegionManager;
import core.game.world.update.flag.context.Graphics;
import core.tools.RandomFunction;
import java.util.ArrayList;
import java.util.List;
import static core.game.node.entity.combat.MultihitTargetsKt.findMultihitTargetsForChinchompa;
/**
* Handles a combat swing using red chinchompas.
* @author Emperor
@ -56,22 +55,18 @@ public final class ChinchompaSwingHandler extends RangeSwingHandler {
return -1;
}
// ! Initial capacity of 14, but has dynamic size? i.e. we are not restricting to a max of 14 targets hit here now
List<Entity> targetCandidates = new ArrayList<>(14);
targetCandidates.addAll(RegionManager.getSurroundingNPCs(victim, 14, entity));
targetCandidates.addAll(RegionManager.getSurroundingPlayers(victim, 14, entity));
boolean accurate = isAccurateImpact(entity, victim, CombatStyle.RANGE);
List<Entity> targetCandidates = findMultihitTargetsForChinchompa(victim, entity);
BattleState[] targets = new BattleState[targetCandidates.size()];
int count = 0;
for (Entity e : targetCandidates) {
if (canSwing(entity, e) != InteractionType.NO_INTERACT && e.isAttackable(entity, CombatStyle.RANGE, false)) {
BattleState s = targets[count++] = new BattleState(entity, e);
s.setStyle(CombatStyle.RANGE);
int hit = 0;
if (isAccurateImpact(entity, e, CombatStyle.RANGE)) {
hit = RandomFunction.random(calculateHit(entity, e, 1.0) + 1);
}
s.setEstimatedHit(hit);
BattleState s = targets[count++] = new BattleState(entity, e);
s.setStyle(CombatStyle.RANGE);
int hit = 0;
if (accurate) {
hit = RandomFunction.random(calculateHit(entity, e, 1.0) + 1);
}
s.setEstimatedHit(hit);
}
state.setTargets(targets);
Companion.useAmmo(entity, state, null);

View file

@ -5,12 +5,9 @@ import java.util.List;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.BattleState;
import core.game.node.entity.combat.CombatStyle;
import core.game.node.entity.combat.InteractionType;
import core.game.node.entity.combat.MeleeSwingHandler;
import core.game.node.entity.impl.Animator.Priority;
import core.game.node.entity.npc.NPC;
import core.game.node.entity.player.Player;
import core.game.world.map.RegionManager;
import core.game.world.update.flag.context.Animation;
import core.game.world.update.flag.context.Graphics;
import core.plugin.Plugin;
@ -19,6 +16,7 @@ import core.tools.RandomFunction;
import org.rs09.consts.Sounds;
import static core.api.ContentAPIKt.playGlobalAudio;
import static core.game.node.entity.combat.MultihitTargetsKt.findMultihitTargetsForD2h;
/**
* Handles the Powerstab special attack.
@ -75,21 +73,17 @@ public final class PowerstabSpecialHandler extends MeleeSwingHandler implements
if (!multi) {
return super.swing(entity, victim, state);
}
@SuppressWarnings("rawtypes")
List list = victim instanceof NPC ? RegionManager.getSurroundingNPCs(entity, 9, entity) : RegionManager.getSurroundingPlayers(entity, 9, entity);
List<Entity> list = findMultihitTargetsForD2h(entity, CombatStyle.MELEE);
BattleState[] targets = new BattleState[list.size()];
int count = 0;
for (Object o : list) {
Entity e = (Entity) o;
if (CombatStyle.RANGE.getSwingHandler().canSwing(entity, e) != InteractionType.NO_INTERACT && e.isAttackable(entity, CombatStyle.RANGE, false)) {
BattleState s = targets[count++] = new BattleState(entity, e);
int hit = 0;
if (isAccurateImpact(entity, e)) {
hit = RandomFunction.random(calculateHit(entity, e, 1.0) + 1);
}
s.setStyle(CombatStyle.MELEE);
s.setEstimatedHit(hit);
for (Entity e : list) {
BattleState s = targets[count++] = new BattleState(entity, e);
int hit = 0;
if (isAccurateImpact(entity, e)) {
hit = RandomFunction.random(calculateHit(entity, e, 1.0) + 1);
}
s.setStyle(CombatStyle.MELEE);
s.setEstimatedHit(hit);
}
state.setTargets(targets);
return 1;

View file

@ -5,12 +5,9 @@ import java.util.List;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.BattleState;
import core.game.node.entity.combat.CombatStyle;
import core.game.node.entity.combat.InteractionType;
import core.game.node.entity.combat.MeleeSwingHandler;
import core.game.node.entity.impl.Animator.Priority;
import core.game.node.entity.npc.NPC;
import core.game.node.entity.player.Player;
import core.game.world.map.RegionManager;
import core.game.world.update.flag.context.Animation;
import core.game.world.update.flag.context.Graphics;
import core.plugin.Plugin;
@ -19,6 +16,7 @@ import core.tools.RandomFunction;
import org.rs09.consts.Sounds;
import static core.api.ContentAPIKt.playGlobalAudio;
import static core.game.node.entity.combat.MultihitTargetsKt.findMultihitTargets;
/**
* Handles Vesta's Spear special attack - Spear Wall.
@ -76,19 +74,14 @@ public final class SpearWallSpecialHandler extends MeleeSwingHandler implements
if (!multi) {
return super.swing(entity, victim, state);
}
@SuppressWarnings("rawtypes")
List list = victim instanceof NPC ? RegionManager.getSurroundingNPCs(entity, 9, entity) : RegionManager.getSurroundingPlayers(entity, 9, entity);
List<Entity> list = findMultihitTargets(victim, entity, CombatStyle.MELEE);
BattleState[] targets = new BattleState[list.size()];
int count = 0;
for (Object o : list) {
Entity e = (Entity) o;
if (CombatStyle.RANGE.getSwingHandler().canSwing(entity, e) != InteractionType.NO_INTERACT && e.isAttackable(entity, CombatStyle.RANGE, false)) {
BattleState s = targets[count++] = new BattleState(entity, e);
int hit = 0;
hit = RandomFunction.random(calculateHit(entity, e, 1.0) + 1);
s.setStyle(CombatStyle.MELEE);
s.setEstimatedHit(hit);
}
for (Entity e : list) {
BattleState s = targets[count++] = new BattleState(entity, e);
int hit = RandomFunction.random(calculateHit(entity, e, 1.0) + 1);
s.setStyle(CombatStyle.MELEE);
s.setEstimatedHit(hit);
}
state.setTargets(targets);
return 1;

View file

@ -4,17 +4,12 @@ import java.util.ArrayList;
import java.util.List;
import core.plugin.Initializable;
import content.global.skill.summoning.familiar.Familiar;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.BattleState;
import core.game.node.entity.combat.CombatStyle;
import core.game.node.entity.combat.MeleeSwingHandler;
import core.game.node.entity.impl.Animator.Priority;
import core.game.node.entity.npc.NPC;
import core.game.node.entity.player.Player;
import core.game.world.map.Direction;
import core.game.world.map.Location;
import core.game.world.map.RegionManager;
import core.game.world.update.flag.context.Animation;
import core.game.world.update.flag.context.Graphics;
import core.plugin.Plugin;
@ -22,6 +17,7 @@ import core.tools.RandomFunction;
import org.rs09.consts.Sounds;
import static core.api.ContentAPIKt.playGlobalAudio;
import static core.game.node.entity.combat.MultihitTargetsKt.findMultihitTargetsForDragonHalberd;
/**
* Handles the Dragon halberd special attack.
@ -92,25 +88,11 @@ public final class SweepSpecialHandler extends MeleeSwingHandler implements Plug
if (!entity.getProperties().isMultiZone() || !victim.getProperties().isMultiZone()) {
return new BattleState[]{state};
}
Location vl = victim.getLocation();
int x = vl.getX();
int y = vl.getY();
Direction dir = Direction.getDirection(x - entity.getLocation().getX(), y - entity.getLocation().getY());
List<BattleState> l = new ArrayList<>(20);
l.add(new BattleState(entity, victim));
for (Entity n : victim instanceof NPC ? RegionManager.getSurroundingNPCs(victim, 9, entity, victim) : RegionManager.getSurroundingPlayers(victim, 9, entity, victim)) {
if (n instanceof Familiar) {
continue;
}
if (!n.isAttackable(entity, CombatStyle.MELEE, false)) {
continue;
}
if (n.getLocation().equals(vl.transform(dir.getStepY(), dir.getStepX(), 0)) || n.getLocation().equals(vl.transform(-dir.getStepY(), -dir.getStepX(), 0))) {
l.add(new BattleState(entity, n));
if (l.size() >= 3) {
break;
}
}
List<Entity> list = findMultihitTargetsForDragonHalberd(victim, entity);
for (Entity n : list) {
l.add(new BattleState(entity, n));
}
return l.toArray(new BattleState[l.size()]);
}

View file

@ -136,7 +136,7 @@ public final class SoftclayPlugin extends UseWithHandler {
player.getPacketDispatch().sendMessage("You mix the clay and water. You now have some soft, workable clay.");
player.getInventory().add(SOFT_CLAY);
player.getInventory().add(returnItem);
if (!player.getAchievementDiaryManager().hasCompletedTask(DiaryType.LUMBRIDGE, 0, 6) && player.getViewport().getRegion().getId() == 12341) {
if (!player.getAchievementDiaryManager().hasCompletedTask(DiaryType.LUMBRIDGE, 0, 6) && player.getLocation().getRegionId() == 12341) {
player.getAchievementDiaryManager().finishTask(player, DiaryType.LUMBRIDGE, 0, 6);
}
return true;

View file

@ -15,30 +15,19 @@ import org.rs09.consts.Sounds
* @author Ceikry
*/
class WaterSourceListener : InteractionListener {
// NOTE '9695' should be removed from the array below once the sink object can be used directly, this is a temporary
// solution.
// this is ugly!
private val waterSources = intArrayOf(21355, 16302, 6827, 11661, 24160, 34577, 15936, 15937, 15938, 23920, 35469, 24265, 153, 879, 880, 2864, 6232, 10436, 10437, 10827, 11007, 11759, 21764, 22973, 24161, 24214, 24265, 28662, 30223, 30820, 34579, 36781, 873, 874, 4063, 6151, 8699, 9143, 9684, 9695, 10175, 12279, 12974, 13563, 13564, 14868, 14917, 14918, 15678, 16704, 16705, 20358, 22715, 24112, 24314, 25729, 25929, 26966, 29105, 33458, 34082, 34411, 34496, 34547, 34566, 35762, 36971, 37154, 37155, 878, 884, 3264, 3305, 3359, 4004, 4005, 6097, 6249, 6549, 8747, 8927, 11793, 12201, 12897, 24166, 26945, 31359, 32023, 32024, 34576, 35671, 40063, 13561, 13563, 13559, 12089)
private val waterSources = intArrayOf(21355, 16302, 6827, 11661, 24160, 34577, 15936, 15937, 15938, 23920, 35469, 24265, 153, 879, 880, 2864, 6232, 10436, 10437, 10827, 11007, 11759, 21764, 22973, 24161, 24214, 24265, 28662, 30223, 30820, 34579, 36781, 873, 874, 4063, 6151, 8699, 9143, 9684, 10175, 12279, 12974, 13563, 13564, 14868, 14917, 14918, 15678, 16704, 16705, 20358, 22715, 24112, 24314, 25729, 25929, 26966, 29105, 33458, 34082, 34411, 34496, 34547, 34566, 35762, 36971, 37154, 37155, 878, 884, 3264, 3305, 3359, 4004, 4005, 6097, 6249, 6549, 8747, 8927, 11793, 12201, 12897, 24166, 26945, 31359, 32023, 32024, 34576, 35671, 40063, 13561, 13563, 13559, 12089)
private val nonWellableMsg = "If I drop my @ down there, I don't think I'm likely to get it back."
private val animation = Animation(832)
override fun defineListeners()
{
override fun defineListeners() {
onUseWith(IntType.SCENERY, WaterVessel.getInputs(), *waterSources){ player, used, with ->
val vessel = WaterVessel.forId(used.id) ?: return@onUseWith false
if(with.name.contains("well", ignoreCase = true) && !vessel.wellable)
{
sendMessage(player, formatMsgText(used.name, nonWellableMsg))
return@onUseWith true
}
if(with.id == 9695 && player.location.regionId != 11571)
{
return@onUseWith false
}
//ugly achievement code, achievement system sux
if(vessel == WaterVessel.BUCKET && with.id == 11661)
{
@ -67,15 +56,6 @@ class WaterSourceListener : InteractionListener {
return@onUseWith true
}
// This is needed to make the crafting guild sink work, but technically it's wrong as it is the noticeboard and
// not the sink being used. This is a temporary solution until the sink object can be used directly.
setDest(IntType.SCENERY, intArrayOf(9695), "use") { player, node ->
if (player.location.regionId == 11571){
return@setDest Location.create(2934, 3280, 0)
}
return@setDest node.location
}
}
private fun formatMsgText(name: String, template: String): String

View file

@ -413,7 +413,7 @@ class TableListener : InteractionListener {
}
val droppedItem = used.dropItem
if (droppedItem.id == Items.COINS_995) playAudio(player, DROP_COINS_SOUND) else playAudio(player, DROP_ITEM_SOUND)
GroundItemManager.create(droppedItem, Location(nearestX, nearestY), player)
GroundItemManager.create(droppedItem, Location(nearestX, nearestY, player.location.z), player)
setAttribute(player, "droppedItem:${droppedItem.id}", getWorldTicks() + 2)
PlayerParser.save(player)

View file

@ -229,7 +229,7 @@ public final class BrimhavenArena extends MapZone implements Plugin<Object> {
DISPENSERS[index++] = Location.create(x, y, 3);
}
}
GameWorld.getPulser().submit(new Pulse(1) {
GameWorld.getPulser().submit(new Pulse(1) {
@Override
public boolean pulse() {
Region r = RegionManager.forId(11157);
@ -237,9 +237,11 @@ public final class BrimhavenArena extends MapZone implements Plugin<Object> {
return false;
}
if (GameWorld.getTicks() % 100 == 0) {
for (RegionPlane plane : r.getPlanes()) {
for (Player player : plane.getPlayers()) {
setDispenser(player);
for (int z = 0; z < 4; z++) {
for (Player player : r.assemblePlayerList(z)) {
if (player != null) {
setDispenser(player);
}
}
}
handlePlankSwitching();
@ -248,19 +250,19 @@ public final class BrimhavenArena extends MapZone implements Plugin<Object> {
if (GameWorld.getTicks() % ticks == 0) {
sawBladeActive = !sawBladeActive;
if (sawBladeActive) {
Scenery object = RegionManager.getObject(3, 2788, 9579);
Scenery object = RegionManager.getObject(2788, 9579, 3);
SceneryBuilder.replace(object, object.transform(3567, object.getRotation(), 10), ticks);
object = RegionManager.getObject(3, 2789, 9579);
object = RegionManager.getObject(2789, 9579, 3);
SceneryBuilder.replace(object, object.transform(0), ticks);
object = RegionManager.getObject(3, 2783, 9551);
object = RegionManager.getObject(2783, 9551, 3);
SceneryBuilder.replace(object, object.transform(3567, object.getRotation(), 10), ticks);
object = RegionManager.getObject(3, 2783, 9552);
object = RegionManager.getObject(2783, 9552, 3);
SceneryBuilder.replace(object, object.transform(0), ticks);
object = RegionManager.getObject(3, 2761, 9584);
object = RegionManager.getObject(2761, 9584, 3);
SceneryBuilder.replace(object, object.transform(3567, object.getRotation(), 10), ticks);
object = RegionManager.getObject(3, 2761, 9585);
object = RegionManager.getObject(2761, 9585, 3);
SceneryBuilder.replace(object, object.transform(0), ticks);
}
}

View file

@ -241,7 +241,7 @@ public final class BuildRoomDialogue extends DialoguePlugin {
}
int rotation = directions[index].toInteger();
boundaries.clear();
Location base = player.getViewport().getRegion().getBaseLocation().transform(roomX << 3, roomY << 3, player.getLocation().getZ());
Location base = player.getLocation().getRegion().getBaseLocation().transform(roomX << 3, roomY << 3, player.getLocation().getZ());
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 8; y++) {
Scenery[] objects = room.getChunk().getObjects(x, y);

View file

@ -8,10 +8,7 @@ import core.game.node.item.Item;
import core.game.node.scenery.Scenery;
import core.game.node.scenery.SceneryBuilder;
import core.game.system.task.Pulse;
import core.game.world.map.BuildRegionChunk;
import core.game.world.map.Direction;
import core.game.world.map.Location;
import core.game.world.map.Region;
import core.game.world.map.*;
import core.game.world.update.flag.context.Animation;
import core.net.packet.PacketRepository;
import core.net.packet.context.ContainerContext;
@ -250,7 +247,7 @@ public final class BuildingUtils {
if (reg == null) {
continue;
}
BuildRegionChunk chunk = (BuildRegionChunk) reg.getPlanes()[plane % 3].getChunks()[l.getChunkX()][l.getChunkY()];
RegionChunk chunk = reg.getChunks()[l.getChunkX()][l.getChunkY()][plane % 3];
Scenery[] objects = chunk.getObjects(h.getCurrentX(), h.getCurrentY());
for (Scenery o : objects) {
if (o != null && o.getType() == object.getType()) {
@ -284,16 +281,19 @@ public final class BuildingUtils {
hotspot.setDecorationIndex(decIndex);
break;
case RECURSIVE:
BuildRegionChunk chunk = (BuildRegionChunk) region.getPlanes()[l.getZ()].getChunks()[l.getChunkX()][l.getChunkY()];
RegionChunk chunk = region.getChunks()[l.getChunkX()][l.getChunkY()][l.getZ()];
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 8; y++) {
Hotspot h = room.getHotspot(hotspot.getHotspot(), x, y);
if (h != null) {
h.setDecorationIndex(decIndex);
int objectId = hotspot.getHotspot().getObjectId(style);
Scenery o = chunk.get(x, y, chunk.getIndex(x, y, objectId));
if (o != null && objectId == o.getId()) {
SceneryBuilder.replace(o, o.transform(hotspot.getHotspot().getDecorations()[decIndex].getObjectId(style)));
int index = chunk.getIndex(x, y, objectId, -1);
if (index != -1) {
Scenery o = chunk.getObjects()[x][y][index];
if (objectId == o.getId()) {
SceneryBuilder.replace(o, o.transform(hotspot.getHotspot().getDecorations()[decIndex].getObjectId(style)));
}
}
}
}
@ -301,7 +301,7 @@ public final class BuildingUtils {
break;
case LINKED:
BuildHotspot[] linkedHotspots = BuildHotspot.getLinkedHotspots(hotspot.getHotspot());
chunk = (BuildRegionChunk) region.getPlanes()[l.getZ()].getChunks()[l.getChunkX()][l.getChunkY()];
chunk = region.getChunks()[l.getChunkX()][l.getChunkY()][l.getZ()];
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 8; y++) {
for (BuildHotspot bh : linkedHotspots) {
@ -309,9 +309,12 @@ public final class BuildingUtils {
if (h != null) {
h.setDecorationIndex(decIndex);
int objectId = bh.getObjectId(style);
Scenery o = chunk.get(x, y, chunk.getIndex(x, y, objectId));
if (o != null && objectId == o.getId()) {
SceneryBuilder.replace(o, o.transform(bh.getDecorations()[decIndex].getObjectId(style)));
int index = chunk.getIndex(x, y, objectId, -1);
if (index != -1) {
Scenery o = chunk.getObjects()[x][y][index];
if (objectId == o.getId()) {
SceneryBuilder.replace(o, o.transform(bh.getDecorations()[decIndex].getObjectId(style)));
}
}
}
}
@ -385,7 +388,7 @@ public final class BuildingUtils {
if (reg == null) {
continue;
}
BuildRegionChunk chunk = (BuildRegionChunk) reg.getPlanes()[plane % 3].getChunks()[l.getChunkX()][l.getChunkY()];
RegionChunk chunk = reg.getChunks()[l.getChunkX()][l.getChunkY()][plane % 3];
Scenery[] objects = chunk.getObjects(h.getCurrentX(), h.getCurrentY());
for (Scenery o : objects) {
if (o != null && o.getType() == object.getType()) {
@ -417,13 +420,14 @@ public final class BuildingUtils {
hotspot.setDecorationIndex(-1);
break;
case RECURSIVE:
BuildRegionChunk chunk = (BuildRegionChunk) region.getPlanes()[l.getZ()].getChunks()[l.getChunkX()][l.getChunkY()];
RegionChunk chunk = region.getChunks()[l.getChunkX()][l.getChunkY()][l.getZ()];
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 8; y++) {
Hotspot h = room.getHotspot(hotspot.getHotspot(), x, y);
if (h != null) {
int objectId = hotspot.getHotspot().getDecorations()[h.getDecorationIndex()].getObjectId(style);
Scenery o = chunk.get(x, y, chunk.getIndex(x, y, objectId));
int index = chunk.getIndex(x, y, objectId, -1);
Scenery o = chunk.getObjects()[x][y][index];
h.setDecorationIndex(-1);
if (o != null && objectId == o.getId()) {
SceneryBuilder.replace(o, o.transform(hotspot.getHotspot().getObjectId(style)));
@ -434,14 +438,15 @@ public final class BuildingUtils {
break;
case LINKED:
BuildHotspot[] linkedHotspots = BuildHotspot.getLinkedHotspots(hotspot.getHotspot());
chunk = (BuildRegionChunk) region.getPlanes()[l.getZ()].getChunks()[l.getChunkX()][l.getChunkY()];
chunk = region.getChunks()[l.getChunkX()][l.getChunkY()][l.getZ()];
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 8; y++) {
for (BuildHotspot bh : linkedHotspots) {
Hotspot h = room.getHotspot(bh, x, y);
if (h != null) {
int objectId = bh.getDecorations()[h.getDecorationIndex()].getObjectId(style);
Scenery o = chunk.get(x, y, chunk.getIndex(x, y, objectId));
int index = chunk.getIndex(x, y, objectId, -1);
Scenery o = chunk.getObjects()[x][y][index];
h.setDecorationIndex(-1);
if (o != null && objectId == o.getId()) {
SceneryBuilder.replace(o, o.transform(bh.getObjectId(style)));

View file

@ -20,19 +20,18 @@ import core.game.world.GameWorld;
import org.rs09.consts.Sounds;
import java.awt.*;
import java.util.ArrayList;
import static core.api.ContentAPIKt.*;
import static core.api.regionspec.RegionSpecificationKt.fillWith;
import static core.api.regionspec.RegionSpecificationKt.using;
/**
* Manages the player's house.
* @author Emperor
*
*/
public final class HouseManager {
/**
* The current region.
*/
@ -97,7 +96,6 @@ public final class HouseManager {
*/
}
public void parse(JSONObject data){
location = HouseLocation.values()[Integer.parseInt( data.get("location").toString())];
style = HousingStyle.values()[Integer.parseInt( data.get("style").toString())];
@ -195,8 +193,8 @@ public final class HouseManager {
}
private void updateVarbits(Player player, boolean build) {
setVarp(player, 261, build ? 1 : 0);
setVarp(player, 262, getRoomAmount());
setVarp(player, 261, build ? 1 : 0);
setVarp(player, 262, getRoomAmount());
}
private void unlockMusicTrack(Player player) {
@ -241,13 +239,13 @@ public final class HouseManager {
* Reloads the house.
* @param player The player.
* @param buildingMode If building mode should be enabled.
* NOTE: I think we should avoid this method, it might be causing some issues. It's actually really suspicious...
* NOTE: I think we should avoid this method, it might be causing some issues. It's actually really suspicious...
*/
public void reload(Player player, boolean buildingMode) {
int diffX = player.getLocation().getLocalX();
int diffY = player.getLocation().getLocalY();
int diffZ = player.getLocation().getZ();
boolean inDungeon = player.getViewport().getRegion() == dungeonRegion;
boolean inDungeon = player.getLocation().getRegion() == dungeonRegion;
this.buildingMode = buildingMode;
construct();
Location newLoc = (dungeonRegion == null ? houseRegion : (inDungeon ? dungeonRegion : houseRegion)).getBaseLocation().transform(diffX,diffY,diffZ);
@ -260,22 +258,17 @@ public final class HouseManager {
*/
public void expelGuests(Player player) {
if (isLoaded()) {
for (RegionPlane plane : houseRegion.getPlanes()) {
for (Player p : plane.getPlayers()) {
for (int z = 0; z < Region.PLANES; z++) {
ArrayList<Player> players = new ArrayList<>(houseRegion.assemblePlayerList(z));
if (dungeonRegion != null) {
players.addAll(dungeonRegion.assemblePlayerList(z));
}
for (Player p : players) {
if (p != player) {
leave(p);
}
}
}
if (dungeonRegion != null) {
for (RegionPlane plane : dungeonRegion.getPlanes()) {
for (Player p : plane.getPlayers()) {
if (p != player) {
leave(p);
}
}
}
}
}
}
@ -296,7 +289,7 @@ public final class HouseManager {
if (h.getDecorationIndex() > -1) {
Decoration d = h.getHotspot().getDecorations()[h.getDecorationIndex()];
if (d == Decoration.PORTAL) {
return houseRegion.getBaseLocation().transform(x * 8 + h.getChunkX(), y * 8 + h.getChunkY() + 2, 0);
return houseRegion.getBaseLocation().transform(x*RegionChunk.SIZE + h.getChunkX(), y*RegionChunk.SIZE + h.getChunkY() + 2, 0);
}
}
}
@ -312,9 +305,9 @@ public final class HouseManager {
*/
public void redecorate(HousingStyle style) {
this.style = style;
for (int z = 0; z < 4; z++) {
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 8; y++) {
for (int z = 0; z < Region.PLANES; z++) {
for (int x = 0; x < RegionChunk.SIZE; x++) {
for (int y = 0; y < RegionChunk.SIZE; y++) {
Room room = rooms[z][x][y];
if (room != null) {
room.decorate(style);
@ -329,9 +322,9 @@ public final class HouseManager {
*/
@Deprecated
public void clearRooms() {
for (int z = 0; z < 4; z++) {
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 8; y++) {
for (int z = 0; z < Region.PLANES; z++) {
for (int x = 0; x < RegionChunk.SIZE; x++) {
for (int y = 0; y < RegionChunk.SIZE; y++) {
rooms[z][x][y] = null;
}
}
@ -372,10 +365,9 @@ public final class HouseManager {
}
private DynamicRegion getPreparedRegion() {
ZoneBorders borders = DynamicRegion.reserveArea(8,8);
ZoneBorders borders = DynamicRegion.reserveArea(Region.CHUNKS_SIZE,Region.CHUNKS_SIZE);
DynamicRegion region = new DynamicRegion(-1, borders.getSouthWestX() >> 6, borders.getSouthWestY() >> 6);
region.setBorders(borders);
region.setUpdateAllPlanes(true);
region.setBuild(true);
RegionManager.addRegion(region.getId(), region);
return region;
@ -393,12 +385,12 @@ public final class HouseManager {
}
@Override
public BuildRegionChunk getChunk(int x, int y, int plane, @NotNull DynamicRegion dyn) {
return rooms[plane][x][y].getChunk().copy(dyn.getPlanes()[plane]);
public @Nullable RegionChunk getChunk(int x, int y, int plane, @NotNull DynamicRegion dyn) {
return rooms[plane][x][y].getChunk().copy();
}
@Override
public void afterSetting(@Nullable BuildRegionChunk chunk, int x, int y, int plane, @NotNull DynamicRegion dyn) {
public void afterSetting(@Nullable RegionChunk chunk, int x, int y, int plane, @NotNull DynamicRegion dyn) {
rooms[plane][x][y].loadDecorations(dyn != manager.dungeonRegion ? plane : 3, chunk, manager);
}
}
@ -406,8 +398,8 @@ public final class HouseManager {
private void prepareHouseChunks(HousingStyle style, DynamicRegion target, boolean buildingMode, Room[][][] rooms) {
Region from = RegionManager.forId(style.getRegionId());
Region.load(from, true);
RegionChunk defaultChunk = from.getPlanes()[style.getPlane()].getRegionChunk(1, 0);
RegionChunk defaultSkyChunk = from.getPlanes()[1].getRegionChunk(0,0);
RegionChunk defaultChunk = from.getChunks()[1][0][style.getPlane()];
RegionChunk defaultSkyChunk = from.getChunks()[0][0][1];
RoomLoadContract loadRooms = new RoomLoadContract(this, buildingMode, rooms);
RegionSpecification spec = new RegionSpecification(
@ -430,7 +422,7 @@ public final class HouseManager {
private void prepareDungeonChunks(HousingStyle style, DynamicRegion target, DynamicRegion house, boolean buildingMode, Room[][] rooms) {
Region from = RegionManager.forId(style.getRegionId());
Region.load(from, true);
RegionChunk defaultChunk = from.getPlanes()[style.getPlane()].getRegionChunk(3, 0);
RegionChunk defaultChunk = from.getChunks()[3][0][style.getPlane()];
RoomLoadContract loadRooms = new RoomLoadContract(this, buildingMode, new Room[][][]{rooms});
RegionSpecification spec = new RegionSpecification(
@ -609,8 +601,8 @@ public final class HouseManager {
int startY = 99;
int endX = 0;
int endY = 0;
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 8; y++) {
for (int x = 0; x < Region.CHUNKS_SIZE; x++) {
for (int y = 0; y < Region.CHUNKS_SIZE; y++) {
if (rooms[0][x][y] != null) {
if (x < startX) startX = x;
if (y < startY) startY = y;
@ -688,7 +680,7 @@ public final class HouseManager {
* @return {@code True} if so.
*/
public boolean isInHouse(Player player) {
return isLoaded() && (player.getViewport().getRegion() == houseRegion || player.getViewport().getRegion() == dungeonRegion);
return isLoaded() && (player.getLocation().getRegion() == houseRegion || player.getLocation().getRegion() == dungeonRegion);
}
/**
@ -697,16 +689,13 @@ public final class HouseManager {
* @return {@code True} if so.
*/
public static boolean isInDungeon(Player player) {
return player.getViewport().getRegion() == player.getHouseManager().dungeonRegion;
return player.getLocation().getRegion() == player.getHouseManager().dungeonRegion;
}
/**
* Checks if the house region was constructed and active.
* @return {@code True} if an active region for the house exists.
*/
//public boolean isLoaded() {
// return (houseRegion != null) || (dungeonRegion != null);
//}
public boolean isLoaded() {
return (houseRegion != null && houseRegion.isActive()) || (dungeonRegion != null && dungeonRegion.isActive());
}

View file

@ -11,37 +11,35 @@ import java.util.Arrays;
*
*/
public enum HousingStyle {
// open door ids are doorId + 1
// open door ids are doorId + 1
BASIC_WOOD (1, 5000, 7503, 0, 13100, 13101, 13098, Decoration.BASIC_WOOD_WINDOW),
BASIC_STONE (10, 5000, 7503, 1, 13094, 13096, 1902, Decoration.BASIC_STONE_WINDOW),
BASIC_STONE (10, 5000, 7503, 1, 13094, 13096, 1902, 13090, Decoration.BASIC_STONE_WINDOW),
WHITEWASHED_STONE (20, 7500, 7503, 2, 13006, 13007, 1415, Decoration.WHITEWASHED_STONE_WINDOW),
FREMENNIK_STYLE_WOOD(30, 10000, 7503, 3, 13109, 13107, 13111, Decoration.FREMENNIK_WINDOW),
TROPICAL_WOOD (40, 15000, 7759, 0, 13016, 13015, 13011, Decoration.TROPICAL_WOOD_WINDOW),
FANCY_STONE (50, 25000, 7759, 1, 13119, 13118, 13116, Decoration.FANCY_STONE_WINDOW);
/**
* Array of all Dungeon Wall IDs.
* From Region 7503, Location.create(1898, 5084, 0)
*/
private static final int[] DUNGEON_WALL_IDS = {
13019, 13020, 13021, 13022, 13023, 13024, 13025, 13026, 13027, 13028,
13029, 13030, 13031, 13032, 13033, 13034, 13035, 13036, 13037, 13046,
13048, 13049, 13050, 13051, 13055, 13056, 13058, 13059, 13060, 13061,
13062, 13063, 13065, 13066, 13067, 13068, 13069, 13070, 13072, 13073,
13074, 13075, 13076, 13077, 13079, 13080, 13081, 13082, 13083, 13084,
13086, 13087, 13088, 13089
};
/**
* Array of all Dungeon Wall IDs.
* From Region 7503, Location.create(1898, 5084, 0)
*/
private static final int[] DUNGEON_WALL_IDS = {
13019, 13020, 13021, 13022, 13023, 13024, 13025, 13026, 13027, 13028,
13029, 13030, 13031, 13032, 13033, 13034, 13035, 13036, 13037, 13046,
13048, 13049, 13050, 13051, 13055, 13056, 13058, 13059, 13060, 13061,
13062, 13063, 13065, 13066, 13067, 13068, 13069, 13070, 13072, 13073,
13074, 13075, 13076, 13077, 13079, 13080, 13081, 13082, 13083, 13084,
13086, 13087, 13088, 13089
};
/**
* Checks if the provided ID is a dungeon wall.
* @param id The object ID.
* @return {@code true} if it's a dungeon wall.
*/
public static boolean isDungeonWall(int id) {
return Arrays.binarySearch(DUNGEON_WALL_IDS, id) >= 0;
}
/**
* Checks if the provided ID is a dungeon wall.
* @param id The object ID.
* @return {@code true} if it's a dungeon wall.
*/
public static boolean isDungeonWall(int id) {
return Arrays.binarySearch(DUNGEON_WALL_IDS, id) >= 0;
}
/**
* The level required.
@ -77,21 +75,26 @@ public enum HousingStyle {
* The wall id.
*/
private final int wallId;
/**
* A second wall id, used for walls behind fireplaces in some house styles.
* Only used for the basic stone house style, who knows why. Same as wallId for other house styles.
*/
private final int secondWallId;
/**
* The window style
*/
private final Decoration window;
/**
* Checks if the player has the level.
*
* @param player the player.
* @return {@code True} if so.
*/
public boolean hasLevel(Player player) {
return player.getSkills().getStaticLevel(Skills.CONSTRUCTION) >= levelRequirement;
}
/**
* Checks if the player has the level.
* @param player the player.
* @return {@code True} if so.
*/
public boolean hasLevel(Player player) {
return player.getSkills().getStaticLevel(Skills.CONSTRUCTION) >= levelRequirement;
}
/**
* Constructs a new {@code HousingStyle} {@code Object}
@ -100,8 +103,12 @@ public enum HousingStyle {
* @param regionId The region id for this style.
* @param plane The plane for this style.
* @param doorId The door object id used in this style.
* @param secondDoorId The second-door object id used in this style.
* @param wallId The wall object id used in this style.
* @param secondWallId The second-wall object id used in this style.
* @param window The window decoration used in this style.
*/
private HousingStyle(int level, int cost, int regionId, int plane, int doorId, int secondDoorId, int wallId, Decoration window) {
HousingStyle(int level, int cost, int regionId, int plane, int doorId, int secondDoorId, int wallId, int secondWallId, Decoration window) {
this.levelRequirement = level;
this.cost = cost;
this.regionId = regionId;
@ -109,6 +116,30 @@ public enum HousingStyle {
this.doorId = doorId;
this.secondDoorId = secondDoorId;
this.wallId = wallId;
this.secondWallId = secondWallId;
this.window = window;
}
/**
* Constructs a new {@code HousingStyle} {@code Object} for housing styles that do not have a second wall id
* @param level The level required.
* @param cost The cost of the style.
* @param regionId The region id for this style.
* @param plane The plane for this style.
* @param doorId The door object id used in this style.
* @param secondDoorId The second-door object id used in this style.
* @param wallId The wall object id used in this style.
* @param window The window decoration used in this style.
*/
HousingStyle(int level, int cost, int regionId, int plane, int doorId, int secondDoorId, int wallId, Decoration window) {
this.levelRequirement = level;
this.cost = cost;
this.regionId = regionId;
this.plane = plane;
this.doorId = doorId;
this.secondDoorId = secondDoorId;
this.wallId = wallId;
this.secondWallId = wallId;
this.window = window;
}
@ -159,7 +190,15 @@ public enum HousingStyle {
public int getWallId() {
return wallId;
}
/**
* Gets the second wall used in this style.
* @return The wall object id.
*/
public int getSecondWallId() {
return secondWallId;
}
/**
* Gets the window id for this style of house
* @return The windows object id
@ -175,4 +214,4 @@ public enum HousingStyle {
public int getSecondDoorId() {
return secondDoorId;
}
}
}

View file

@ -1,6 +1,5 @@
package content.global.skill.construction;
import core.game.node.entity.player.Player;
import core.game.node.scenery.Constructed;
import core.game.node.scenery.Scenery;
@ -16,7 +15,6 @@ import static core.api.ContentAPIKt.log;
*
*/
public final class Room {
/**
* The default room type.
*/
@ -95,7 +93,7 @@ public final class Room {
public void decorate(HousingStyle style) {
Region region = RegionManager.forId(style.getRegionId());
Region.load(region, true);
chunk = region.getPlanes()[style.getPlane()].getRegionChunk(properties.getChunkX(), properties.getChunkY());
chunk = region.getChunks()[properties.getChunkX()][properties.getChunkY()][style.getPlane()];
}
/**
@ -126,63 +124,59 @@ public final class Room {
* Loads all the decorations.
* @param housePlane The plane.
* @param chunk The chunk used in the dynamic region.
*/
public void loadDecorations(int housePlane, BuildRegionChunk chunk, HouseManager house) {
for (int i = 0; i < hotspots.length; i++) {
Hotspot spot = hotspots[i];
*/
public void loadDecorations(int housePlane, RegionChunk chunk, HouseManager house) {
for (Hotspot spot : hotspots) {
int x = spot.getChunkX();
int y = spot.getChunkY();
if (spot.getHotspot() == null) {
continue;
}
int index = chunk.getIndex(x, y, spot.getHotspot().getObjectId(house.getStyle()));
Scenery[][] objects = chunk.getObjects(index);
Scenery object = objects[x][y];
if (object != null && object.getId() == spot.getHotspot().getObjectId(house.getStyle())) {
if (spot.getDecorationIndex() > -1 && spot.getDecorationIndex() < spot.getHotspot().getDecorations().length) {
int id = spot.getHotspot().getDecorations()[spot.getDecorationIndex()].getObjectId(house.getStyle());
if (spot.getHotspot().getType() == BuildHotspotType.CREST) {
id += house.getCrest().ordinal();
int id = spot.getHotspot().getObjectId(house.getStyle());
int index = chunk.getIndex(x, y, id, -1);
if (index != -1) {
Scenery object = chunk.getObjects()[x][y][index];
if (object.getId() == spot.getHotspot().getObjectId(house.getStyle())) {
if (spot.getDecorationIndex() > -1 && spot.getDecorationIndex() < spot.getHotspot().getDecorations().length) {
id = spot.getHotspot().getDecorations()[spot.getDecorationIndex()].getObjectId(house.getStyle());
if (spot.getHotspot().getType() == BuildHotspotType.CREST) {
id += house.getCrest().ordinal();
}
SceneryBuilder.replace(object, object.transform(id, object.getRotation(), chunk.getCurrentBase().transform(x, y, 0)));
} else if (object.getId() == BuildHotspot.WINDOW.getObjectId(house.getStyle()) || (!house.isBuildingMode() && object.getId() == BuildHotspot.CHAPEL_WINDOW.getObjectId(house.getStyle()))) {
SceneryBuilder.replace(object, object.transform(house.getStyle().getWindowStyle().getObjectId(house.getStyle()), object.getRotation(), object.getType()));
}
SceneryBuilder.replace(object, object.transform(id, object.getRotation(), chunk.getCurrentBase().transform(x, y, 0)));
int[] pos = RegionChunk.getRotatedPosition(x, y, object.getSizeX(), object.getSizeY(), 0, rotation.toInteger());
spot.setCurrentX(pos[0]);
spot.setCurrentY(pos[1]);
}
else if (object.getId() == BuildHotspot.WINDOW.getObjectId(house.getStyle()) || (!house.isBuildingMode() && object.getId() == BuildHotspot.CHAPEL_WINDOW.getObjectId(house.getStyle()))) {
chunk.add(object.transform(house.getStyle().getWindowStyle().getObjectId(house.getStyle()), object.getRotation(), object.getType()));
}
int[] pos = RegionChunk.getRotatedPosition(x, y, object.getSizeX(), object.getSizeY(), 0, rotation.toInteger());
spot.setCurrentX(pos[0]);
spot.setCurrentY(pos[1]);
}
}
if (rotation != Direction.NORTH && chunk.getRotation() == 0) {
if (rotation != Direction.NORTH && chunk.getRotation() == 0) { //TODO: it is absolutely insane that this is using Direction.NORTH and such rather than RegionChunk.NORTH_ROTATION and such.
chunk.rotate(rotation);
}
if (!house.isBuildingMode()) {
placeDoors(housePlane, house, chunk);
removeHotspots(housePlane, house, chunk);
removeHotspots(house, chunk);
}
}
/**
* Removes the building hotspots from the room.
* @param housePlane The room's plane in house.
* @param house The house manager.
* @param chunk The region chunk used.
*/
private void removeHotspots(int housePlane, HouseManager house, BuildRegionChunk chunk) {
private void removeHotspots(HouseManager house, RegionChunk chunk) {
if (properties.isRoof()) return;
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 8; y++) {
for (int i = 0; i < BuildRegionChunk.ARRAY_SIZE; i++) {
Scenery object = chunk.get(x, y, i);
for (int i = 0; i < RegionChunk.ARRAY_SIZE; i++) {
Scenery object = chunk.getObjects()[x][y][i];
if (object != null) {
int id = object.getId();
boolean isBuilt = object instanceof Constructed;
boolean isWall = HousingStyle.isDungeonWall(id) || id == house.getStyle().getWallId();
boolean isDoor = id == house.getStyle().getDoorId() || id == house.getStyle().getSecondDoorId();
if (!isBuilt && !isWall && !isDoor) {
int id = object.getId();
boolean isBuilt = !object.getDefinition().hasAction("build");
boolean isGround = object.getType() == 22 && !object.getDefinition().hasOptions();
boolean isWall = HousingStyle.isDungeonWall(id) || id == house.getStyle().getWallId() || id == house.getStyle().getSecondWallId();
boolean isDoor = id == house.getStyle().getDoorId() || id == house.getStyle().getSecondDoorId();
if (!isBuilt && !isGround && !isWall && !isDoor) {
SceneryBuilder.remove(object);
chunk.remove(object);
}
}
}
@ -197,14 +191,14 @@ public final class Room {
* @param house The house manager.
* @param chunk The region chunk used.
*/
private void placeDoors(int housePlane, HouseManager house, BuildRegionChunk chunk) {
private void placeDoors(int housePlane, HouseManager house, RegionChunk chunk) {
Room[][][] rooms = house.getRooms();
int rx = chunk.getCurrentBase().getChunkX();
int ry = chunk.getCurrentBase().getChunkY();
for (int i = 0; i < BuildRegionChunk.ARRAY_SIZE; i++) {
for (int i = 0; i < RegionChunk.ARRAY_SIZE; i++) {
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 8; y++) {
Scenery object = chunk.get(x, y, i);
Scenery object = chunk.getObjects()[x][y][i];
if (object != null && BuildingUtils.isDoorHotspot(object)) {
boolean edge = false;
Room otherRoom = null;
@ -274,7 +268,7 @@ public final class Room {
return object.getId() % 2 != 0 ? house.getStyle().getDoorId() : house.getStyle().getSecondDoorId();
}
}
return room.getProperties().isDungeon() ? 13065 : house.getStyle().getWallId();
return room.getProperties().isDungeon() ? 13065 : house.getStyle().getWallId(); //otherWallId is only used behind fireplaces
}
/**
@ -423,5 +417,4 @@ public final class Room {
public Direction getRotation() {
return rotation;
}
}

View file

@ -920,7 +920,7 @@ public enum RoomProperties {
public boolean[] getExits() {
Region region = RegionManager.forId(7503);
Region.load(region, true);
RegionChunk chunk = region.getPlanes()[0].getRegionChunk(chunkX, chunkY);
RegionChunk chunk = region.getChunks()[chunkX][chunkY][0];
return new boolean[] { isExit(chunk, 7, 3), isExit(chunk, 3, 0), isExit(chunk, 0, 3), isExit(chunk, 3, 7) };
}

View file

@ -29,18 +29,18 @@ public final class StaircasePlugin extends OptionHandler {
public Plugin<Object> newInstance(Object arg) throws Throwable {
ClassScanner.definePlugin(new BuildDialogue());
ClassScanner.definePlugin(new ClimbPohLadder());
// 13497 - 13502 are normal stairs
// 13503 - 13506 are spiral stairs
// 13497 - 13502 are normal stairs
// 13503 - 13506 are spiral stairs
for (int i = 13497; i <= 13506; i++) {
SceneryDefinition.forId(i).getHandlers().put("option:climb", this);
SceneryDefinition.forId(i).getHandlers().put("option:climb-up", this);
SceneryDefinition.forId(i).getHandlers().put("option:climb-down", this);
SceneryDefinition.forId(i).getHandlers().put("option:remove-room", this);
}
// 13409 is dungeon entrance
// 13409 is dungeon entrance
SceneryDefinition.forId(13409).getHandlers().put("option:enter", this);
SceneryDefinition.forId(13409).getHandlers().put("option:remove-room", this);
// 13328 - 13330 are dungeon ladders
// 13328 - 13330 are dungeon ladders
for (int id = 13328; id <= 13330; id++) {
SceneryDefinition.forId(id).getHandlers().put("option:climb", this);
SceneryDefinition.forId(id).getHandlers().put("option:remove-room", this);
@ -73,45 +73,43 @@ public final class StaircasePlugin extends OptionHandler {
SceneryBuilder.replace(object, object.transform(object.getId() - 3));
return true;
case "remove-room":
int currentZ = player.getLocation().getZ();
int chunkX = player.getLocation().getChunkX();
int chunkY = player.getLocation().getChunkY();
int currentZ = player.getLocation().getZ();
int chunkX = player.getLocation().getChunkX();
int chunkY = player.getLocation().getChunkY();
// must be in building mode
if(!player.getHouseManager().isBuildingMode()) {
player.getPacketDispatch().sendMessage("You can only do this in building mode.");
return true;
}
// must be in building mode
if(!player.getHouseManager().isBuildingMode()) {
player.getPacketDispatch().sendMessage("You can only do this in building mode.");
return true;
}
// if you're in the dungeon, try and remove the room at Z = 0 from the house region.
if (HouseManager.isInDungeon(player)) {
player.getDialogueInterpreter().open("con:remove", null, new int[]{chunkX, chunkY}, 0);
// if you're in the dungeon, try and remove the room at Z = 0 from the house region.
if (HouseManager.isInDungeon(player)) {
player.getDialogueInterpreter().open("con:remove", null, new int[]{chunkX, chunkY}, 0);
// From ground floor (z=0), stairs could lead to 1st floor (z=1) or the dungeon (z=3)
} else {
// garden dungeon entrance and oubliette ladders don't need a height selection
if (node.getId() == 13409 || node.getId() == 13675 || node.getId() == 13676 || node.getId() == 13677 || node.getId() == 13678 || node.getId() == 13679 || node.getId() == 13680) {
player.getDialogueInterpreter().open("con:remove", null, new int[]{chunkX, chunkY}, 3);
} else {
player.getDialogueInterpreter().sendOptions("Remove which room?", "Room Above", "Room Below", "Cancel");
player.getDialogueInterpreter().addAction((interId, btn) -> {
if (btn == 2) { // Above
player.getDialogueInterpreter().open("con:remove", null, new int[]{chunkX, chunkY}, currentZ + 1);
} else if (btn == 3) { // Below
if (currentZ - 1 == -1) {
player.getDialogueInterpreter().open("con:remove", null, new int[]{chunkX, chunkY}, 3);
} else {
player.getDialogueInterpreter().open("con:remove", null, new int[]{chunkX, chunkY}, currentZ - 1);
}
// From ground floor (z=0), stairs could lead to 1st floor (z=1) or the dungeon (z=3)
} else {
// garden dungeon entrance and oubliette ladders don't need a height selection
if(node.getId() == 13409 || node.getId() == 13675 || node.getId() == 13676 || node.getId() == 13677 || node.getId() == 13678 || node.getId() == 13679 || node.getId() == 13680) {
player.getDialogueInterpreter().open("con:remove", null, new int[]{chunkX, chunkY}, 3);
} else {
player.getDialogueInterpreter().sendOptions("Remove which room?", "Room Above", "Room Below", "Cancel");
player.getDialogueInterpreter().addAction((interId, btn) -> {
if (btn == 2) { // Above
player.getDialogueInterpreter().open("con:remove", null, new int[]{chunkX, chunkY}, currentZ + 1);
} else if (btn == 3) { // Below
if (currentZ - 1 == -1) {
player.getDialogueInterpreter().open("con:remove", null, new int[]{chunkX, chunkY}, 3);
} else {
player.getDialogueInterpreter().open("con:remove", null, new int[]{chunkX, chunkY}, currentZ - 1);
}
}
});
}
}
return true;
}
});
}
}
return true;
case "climb":
if (HouseManager.isInDungeon(player)) {
climb(player, 1, house, object);
@ -151,7 +149,7 @@ public final class StaircasePlugin extends OptionHandler {
if (plane < 0) { //Dungeon
plane = 3;
}
else if (player.getViewport().getRegion() == house.getDungeonRegion() && plane == 1) {//going up
else if (player.getLocation().getRegion() == house.getDungeonRegion() && plane == 1) {//going up
plane = 0;
}
Room room = house.getRooms()[plane][roomX][roomY];
@ -165,7 +163,7 @@ public final class StaircasePlugin extends OptionHandler {
}
} else {
Location destination = l.transform(0, 0, z);
if (player.getViewport().getRegion() == house.getDungeonRegion()) {
if (player.getLocation().getRegion() == house.getDungeonRegion()) {
destination = house.getHouseRegion().getBaseLocation().transform(l.getLocalX(), l.getLocalY(), 0);
}
else if (plane == 3) {
@ -417,7 +415,7 @@ public final class StaircasePlugin extends OptionHandler {
for (Direction d : dirs) {
if (d == room.getRotation()) {
r.setRotation(d);
// todo this just puts a default set of stairs in the dungeon. The below code works for skill/quest hall, but not a dungeon entrance.
// todo this just puts a default set of stairs in the dungeon. The below code works for skill/quest hall, but not a dungeon entrance.
//Hotspot stairs = room.getStairs();
//int index = stairs != null ? stairs.getDecorationIndex() : -1;
BuildingUtils.buildRoom(player, r, plane, roomX, roomY, r.getExits(), true);
@ -475,4 +473,4 @@ public final class StaircasePlugin extends OptionHandler {
}
}
}
}

View file

@ -8,7 +8,6 @@ import core.game.node.entity.skill.Skills;
import core.game.interaction.NodeUsageEvent;
import core.game.interaction.UseWithHandler;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.audio.Audio;
import core.game.node.item.Item;
import core.game.node.scenery.Scenery;
import core.game.system.task.Pulse;
@ -60,11 +59,11 @@ public class BoneOfferPlugin extends UseWithHandler {
Scenery left = null;
Scenery right = null;
if (event.getUsedWith().asScenery().getRotation() % 2 == 0) {
left = RegionManager.getObject(event.getUsedWith().getLocation().getZ(), event.getUsedWith().getLocation().getX() + 3, event.getUsedWith().getLocation().getY());
right = RegionManager.getObject(event.getUsedWith().getLocation().getZ(), event.getUsedWith().getLocation().getX() - 2, event.getUsedWith().getLocation().getY());
left = RegionManager.getObject(event.getUsedWith().getLocation().getX() + 3, event.getUsedWith().getLocation().getY(), event.getUsedWith().getLocation().getZ());
right = RegionManager.getObject(event.getUsedWith().getLocation().getX() - 2, event.getUsedWith().getLocation().getY(), event.getUsedWith().getLocation().getZ());
} else {
left = RegionManager.getObject(event.getUsedWith().getLocation().getZ(), event.getUsedWith().getLocation().getX(), event.getUsedWith().getLocation().getY() + 3);
right = RegionManager.getObject(event.getUsedWith().getLocation().getZ(), event.getUsedWith().getLocation().getX(), event.getUsedWith().getLocation().getY() - 2);
left = RegionManager.getObject(event.getUsedWith().getLocation().getX(), event.getUsedWith().getLocation().getY() + 3, event.getUsedWith().getLocation().getZ());
right = RegionManager.getObject(event.getUsedWith().getLocation().getX(), event.getUsedWith().getLocation().getY() - 2, event.getUsedWith().getLocation().getZ());
}
Bones b = Bones.forId(event.getUsedItem().getId());
if (b != null) {

View file

@ -525,7 +525,7 @@ public class HouseServantDialogue extends DialoguePlugin {
@Override
public boolean pulse() {
if (player == null || player.getHouseManager().getHouseRegion() != player.getViewport().getRegion()) { //TODO: Check if in dungeon?
if (player == null || player.getHouseManager().getHouseRegion() != player.getLocation().getRegion()) { //TODO: Check if in dungeon?
return true;
}
int amt = player.getBank().getAmount(item.getId());

View file

@ -76,13 +76,13 @@ public final class SpinningPulse extends SkillPulse<Item> {
@Override
public boolean reward() {
int tickThreshhold = 4;
if (player.getAchievementDiaryManager().getDiary(DiaryType.SEERS_VILLAGE).isComplete(2)
&& player.getLocation().withinDistance(Location.create(2711,3471,1))
&& player.getEquipment().get(EquipmentContainer.SLOT_HAT) != null
&& player.getEquipment().get(EquipmentContainer.SLOT_HAT).getId() == 14631) {
tickThreshhold = 2;
}
int tickThreshhold = 4;
if (player.getAchievementDiaryManager().getDiary(DiaryType.SEERS_VILLAGE).isComplete(2)
&& player.getLocation().withinDistance(Location.create(2711,3471,1))
&& player.getEquipment().get(EquipmentContainer.SLOT_HAT) != null
&& player.getEquipment().get(EquipmentContainer.SLOT_HAT).getId() == 14631) {
tickThreshhold = 2;
}
if (++ticks % tickThreshhold != 0) {
return false;
}
@ -92,7 +92,7 @@ public final class SpinningPulse extends SkillPulse<Item> {
player.getSkills().addExperience(Skills.CRAFTING, type.getExp(), true);
// Seers achievement diary
if (player.getViewport().getRegion().getId() == 10806
if (player.getLocation().getRegionId() == 10806
&& !player.getAchievementDiaryManager().getDiary(DiaryType.SEERS_VILLAGE).isComplete(0, 4)) {
if (player.getAttribute("diary:seers:bowstrings-spun", 0) >= 4) {
player.setAttribute("/save:diary:seers:bowstrings-spun", 5);

View file

@ -138,7 +138,7 @@ public final class FireMakingPulse extends SkillPulse<Item> {
player.faceLocation(object.getFaceLocation(player.getLocation()));
player.getSkills().addExperience(Skills.FIREMAKING,fire.getXp());
int playerRegion = player.getViewport().getRegion().getId();
int playerRegion = player.getLocation().getRegionId();
setLastFire();
player.dispatch(new LitFireEvent(fire.getLogId()));

View file

@ -212,12 +212,11 @@ class WoodcuttingListener : InteractionListener {
fun animateWoodcutting(player: Player) {
if (!player.animator.isAnimating) {
player.animate(SkillingTool.getHatchet(player).animation)
val playersAroundMe: List<Player> = RegionManager.getLocalPlayers(player, 2)
val playersAroundMe: List<Player> = RegionManager.getLocalPlayers(player.location, 2)
.stream()
.filter { p: Player -> p.username != player.username }
.filter { p -> p != player }
.toList()
val soundIndex = RandomFunction.random(0, woodcuttingSounds.size)
for (p in playersAroundMe) {
playAudio(p, woodcuttingSounds[soundIndex])
}
@ -260,7 +259,7 @@ class WoodcuttingListener : InteractionListener {
}
// Seers village medium reward - extra normal log while in seer's village
if (reward == 1511 && player.getAchievementDiaryManager().getDiary(DiaryType.SEERS_VILLAGE).isComplete(1) && player.getViewport().getRegion().getId() == 10806) {
if (reward == 1511 && player.achievementDiaryManager.getDiary(DiaryType.SEERS_VILLAGE).isComplete(1) && player.getLocation().regionId == 10806) {
amount = 2
}
return amount

View file

@ -11,7 +11,6 @@ import core.game.dialogue.FacialExpression;
import core.game.node.entity.impl.Animator;
import core.game.node.entity.impl.Projectile;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.audio.Audio;
import core.game.node.entity.player.link.diary.DiaryType;
import core.game.node.entity.skill.Skills;
import content.data.skill.SkillingTool;
@ -25,9 +24,6 @@ import core.game.world.update.flag.context.Animation;
import core.tools.RandomFunction;
import org.rs09.consts.Sounds;
import java.util.List;
import java.util.stream.Collectors;
import static core.api.ContentAPIKt.playAudio;
import static core.game.system.command.sets.StatAttributeKeysKt.STATS_BASE;
import static core.game.system.command.sets.StatAttributeKeysKt.STATS_LOGS;
@ -113,17 +109,13 @@ public class WoodcuttingSkillPulse extends Pulse {
}
public void animate() {
if(!player.getAnimator().isAnimating()) {
if (!player.getAnimator().isAnimating()) {
player.animate(SkillingTool.getHatchet(player).getAnimation());
List<Player> playersAroundMe = RegionManager.getLocalPlayers(player, 2)
.stream()
.filter(p -> !p.getUsername().equals(player.getUsername()))
.collect(Collectors.toList());
int soundIndex = RandomFunction.random(0, woodcuttingSounds.length);
for (Player p : playersAroundMe) {
for (Player p : RegionManager.getLocalPlayers(player.getLocation(), 2)) {
if (p == player) {
continue;
}
playAudio(p, woodcuttingSounds[soundIndex]);
}
}
@ -227,7 +219,7 @@ public class WoodcuttingSkillPulse extends Pulse {
// Seers village medium reward - extra normal log while in seer's village
if (reward == 1511
&& player.getAchievementDiaryManager().getDiary(DiaryType.SEERS_VILLAGE).isComplete(1)
&& player.getViewport().getRegion().getId() == 10806) {
&& player.getLocation().getRegionId() == 10806) {
amount = 2;
}

View file

@ -173,6 +173,6 @@ enum class ImplingSpawnLocations (val type: ImplingSpawnTypes, vararg val locati
object ImplingClipper : ClipMaskSupplier {
override fun getClippingFlag (z: Int, x: Int, y: Int) : Int {
var flag = RegionManager.getClippingFlag(z, x, y)
return flag and (RegionFlags.SOLID_TILE.inv()) and (RegionFlags.TILE_OBJECT.inv()) //Allow walking on water and flying over small objects, but keep all other tile flags the same.
return flag and (ChunkFlags.SOLID_TILE.inv()) and (ChunkFlags.TILE_OBJECT.inv()) //Allow walking on water and flying over small objects, but keep all other tile flags the same.
}
}

View file

@ -2,6 +2,8 @@ package content.global.skill.magic.ancient;
import java.util.List;
import core.game.node.entity.combat.CombatStyle;
import core.game.node.entity.combat.MultihitTargetsKt;
import core.game.node.entity.combat.spell.Runes;
import core.game.node.Node;
import core.game.node.entity.Entity;
@ -118,7 +120,8 @@ public final class BloodSpells extends CombatSpell {
if (animation.getId() == 1978 || !entity.getProperties().isMultiZone() || !target.getProperties().isMultiZone()) {
return super.getTargets(entity, target);
}
List<Entity> list = getMultihitTargets(entity, target, 9);
List<Entity> list = MultihitTargetsKt.findMultihitTargets(target, entity, CombatStyle.MAGIC);
BattleState[] targets = new BattleState[list.size()];
int index = 0;
for (Entity e : list) {

View file

@ -2,6 +2,8 @@ package content.global.skill.magic.ancient;
import java.util.List;
import core.game.node.entity.combat.CombatStyle;
import core.game.node.entity.combat.MultihitTargetsKt;
import core.game.node.entity.combat.spell.Runes;
import core.game.node.Node;
import core.game.node.entity.Entity;
@ -131,10 +133,10 @@ public final class IceSpells extends CombatSpell {
return;
}
int ticks = (type.ordinal() - 4) * 8;
if (hasTimerActive(victim, "frozen") || hasTimerActive(victim, "frozen:immunity")) {
if (type == SpellType.BARRAGE) { state.setFrozen(true); }
return;
}
if (hasTimerActive(victim, "frozen") || hasTimerActive(victim, "frozen:immunity")) {
if (type == SpellType.BARRAGE) { state.setFrozen(true); }
return;
}
registerTimer(victim, spawnTimer("frozen", ticks, true));
}
@ -143,7 +145,8 @@ public final class IceSpells extends CombatSpell {
if (animation.getId() == 1978 || !entity.getProperties().isMultiZone() || !target.getProperties().isMultiZone()) {
return super.getTargets(entity, target);
}
List<Entity> list = getMultihitTargets(entity, target, 9);
List<Entity> list = MultihitTargetsKt.findMultihitTargets(target, entity, CombatStyle.MAGIC);
BattleState[] targets = new BattleState[list.size()];
int index = 0;
for (Entity e : list) {

View file

@ -3,6 +3,8 @@
import java.util.List;
import core.game.container.impl.EquipmentContainer;
import core.game.node.entity.combat.CombatStyle;
import core.game.node.entity.combat.MultihitTargetsKt;
import core.plugin.Initializable;
import core.game.node.entity.combat.spell.Runes;
import core.game.node.Node;
@ -121,7 +123,7 @@ public final class MiasmicSpells extends CombatSpell {
@Override
public void fireEffect(Entity entity, Entity victim, BattleState state) {
if (!hasTimerActive(victim, "miasmic:immunity")) {
registerTimer(victim, spawnTimer("miasmic", (getSpellId() - 15) * 20));
registerTimer(victim, spawnTimer("miasmic", (getSpellId() - 15) * 20));
}
}
@ -142,8 +144,8 @@ public final class MiasmicSpells extends CombatSpell {
@Override
public boolean cast(Entity entity, Node target) {
if (!validStaffEquipped(entity) && !GameWorld.getSettings().isDevMode()) {
((Player) entity).getPacketDispatch().sendMessage("You need to be wielding Zuriel's staff in order to cast this spell.");
return false;
((Player) entity).getPacketDispatch().sendMessage("You need to be wielding Zuriel's staff in order to cast this spell.");
return false;
}
if (!meetsRequirements(entity, true, false)) {
return false;
@ -157,7 +159,8 @@ public final class MiasmicSpells extends CombatSpell {
|| !entity.getProperties().isMultiZone() || !target.getProperties().isMultiZone()) {
return super.getTargets(entity, target);
}
List<Entity> list = getMultihitTargets(entity, target, 9);
List<Entity> list = MultihitTargetsKt.findMultihitTargets(target, entity, CombatStyle.MAGIC);
BattleState[] targets = new BattleState[list.size()];
int index = 0;
for (Entity e : list) {

View file

@ -2,7 +2,8 @@ package content.global.skill.magic.ancient;
import java.util.List;
import core.game.node.entity.player.Player;
import core.game.node.entity.combat.CombatStyle;
import core.game.node.entity.combat.MultihitTargetsKt;
import core.game.node.entity.skill.Skills;
import core.game.node.entity.combat.spell.Runes;
import core.game.node.Node;
@ -115,7 +116,8 @@ public final class ShadowSpells extends CombatSpell {
if (animation.getId() == 1978 || !entity.getProperties().isMultiZone() || !target.getProperties().isMultiZone()) {
return super.getTargets(entity, target);
}
List<Entity> list = getMultihitTargets(entity, target, 9);
List<Entity> list = MultihitTargetsKt.findMultihitTargets(target, entity, CombatStyle.MAGIC);
BattleState[] targets = new BattleState[list.size()];
int index = 0;
for (Entity e : list) {

View file

@ -2,6 +2,8 @@ package content.global.skill.magic.ancient;
import java.util.List;
import core.game.node.entity.combat.CombatStyle;
import core.game.node.entity.combat.MultihitTargetsKt;
import core.game.node.entity.combat.spell.Runes;
import core.game.node.Node;
import core.game.node.entity.Entity;
@ -10,7 +12,6 @@ import core.game.node.entity.combat.spell.CombatSpell;
import core.game.node.entity.combat.spell.SpellType;
import core.game.node.entity.impl.Projectile;
import core.game.node.entity.impl.Animator.Priority;
import core.game.node.entity.player.Player;
import core.game.node.entity.player.link.SpellBookManager.SpellBook;
import core.game.node.item.Item;
import core.game.world.update.flag.context.Animation;
@ -114,7 +115,7 @@ public final class SmokeSpells extends CombatSpell {
@Override
public void fireEffect(Entity entity, Entity victim, BattleState state) {
if (state.getEstimatedHit() > -1) {
applyPoison(victim, entity, type.ordinal() >= SpellType.BLITZ.ordinal() ? 4 : 2);
applyPoison(victim, entity, type.ordinal() >= SpellType.BLITZ.ordinal() ? 4 : 2);
}
}
@ -123,7 +124,8 @@ public final class SmokeSpells extends CombatSpell {
if (animation.getId() == 1978 || !entity.getProperties().isMultiZone() || !target.getProperties().isMultiZone()) {
return super.getTargets(entity, target);
}
List<Entity> list = getMultihitTargets(entity, target, 9);
List<Entity> list = MultihitTargetsKt.findMultihitTargets(target, entity, CombatStyle.MAGIC);
BattleState[] targets = new BattleState[list.size()];
int index = 0;
for (Entity e : list) {

View file

@ -1,5 +1,6 @@
package content.global.skill.magic.lunar;
import core.game.bots.AIPlayer;
import core.game.node.entity.combat.spell.MagicSpell;
import core.game.node.entity.combat.spell.Runes;
import core.plugin.Initializable;
@ -92,7 +93,7 @@ public final class HealSpell extends MagicSpell {
player.getPacketDispatch().sendMessage("This player is busy.");
return false;
}
if (!o.getSettings().isAcceptAid()) {
if (!o.getSettings().isAcceptAid() || (o instanceof AIPlayer)) {
player.getPacketDispatch().sendMessage("The player is not accepting any aid.");
return false;
}
@ -111,11 +112,11 @@ public final class HealSpell extends MagicSpell {
playGlobalAudio(o.getLocation(), Sounds.LUNAR_HEAL_OTHER_INDIVIDUAL_2892);
o.graphics(GRAPHICS);
} else {
List<Player> players = RegionManager.getLocalPlayers(player, 1);
if (!super.meetsRequirements(player, true, true)) {
return false;
}
int percentage = (int) Math.ceil(player.getSkills().getLifepoints() * 0.75);
List<Player> players = RegionManager.getLocalPlayers(player.getLocation(), 1);
for (Iterator<Player> it = players.iterator(); it.hasNext();) {
Player p = it.next();
if (p == player || !p.getSettings().isAcceptAid() || !p.isActive() || p.getSkills().getLifepoints() == p.getSkills().getMaximumLifepoints()) {

View file

@ -501,16 +501,16 @@ class LunarListeners : SpellListener("lunar"), Commands {
removeRunes(player, true)
visualizeSpell(player, Animations.LUNAR_SPELLBOOK_CURE_GROUP_4409, Graphics.LUNAR_SPELLBOOK_CURE_GROUP_744, 130, Sounds.LUNAR_CURE_GROUP_2882)
curePoison(player)
for(acct in RegionManager.getLocalPlayers(player, 1)) {
if(!acct.isActive || acct.locks.isInteractionLocked) {
for (otherPlayer in RegionManager.getLocalPlayers(player.location, 1)) {
if (otherPlayer == player || !otherPlayer.isActive || otherPlayer.locks.isInteractionLocked) {
continue
}
if(!acct.settings.isAcceptAid) {
if (!otherPlayer.settings.isAcceptAid) {
continue
}
curePoison(acct)
sendMessage(acct, "You have been cured of poison.")
visualizeSpell(acct, -1, Graphics.LUNAR_SPELLBOOK_CURE_GROUP_744, 130, Sounds.LUNAR_CURE_OTHER_INDIVIDUAL_2889)
curePoison(otherPlayer)
sendMessage(otherPlayer, "You have been cured of poison.")
visualizeSpell(otherPlayer, -1, Graphics.LUNAR_SPELLBOOK_CURE_GROUP_744, 130, Sounds.LUNAR_CURE_OTHER_INDIVIDUAL_2889)
}
addXP(player, 74.0)
}
@ -836,12 +836,12 @@ class LunarListeners : SpellListener("lunar"), Commands {
}
private fun sendGroupTeleport(player: Player, xp: Double, destName: String, loc: Location){
RegionManager.getLocalPlayers(player, 1).forEach {
if(it == player) return@forEach
if(it.isTeleBlocked) return@forEach
if(!it.isActive) return@forEach
if(!it.settings.isAcceptAid) return@forEach
if(it.ironmanManager.isIronman) return@forEach
RegionManager.getLocalPlayers(player.location, 1).forEach {
if (it == player) return@forEach
if (it.isTeleBlocked) return@forEach
if (!it.isActive) return@forEach
if (!it.settings.isAcceptAid) return@forEach
if (it.ironmanManager.isIronman) return@forEach
setAttribute(it, "t-o_location", loc)
openInterface(it, Components.TELEPORT_OTHER_326)
setInterfaceText(it, player.username, Components.TELEPORT_OTHER_326, 1)

View file

@ -16,6 +16,7 @@ import core.game.world.update.flag.context.Animation;
import core.game.world.update.flag.context.Graphics;
import core.plugin.Initializable;
import core.plugin.Plugin;
import org.rs09.consts.Items;
import org.rs09.consts.Sounds;
import java.util.List;
@ -40,35 +41,37 @@ public final class StatBoostSpell extends MagicSpell {
@Override
public boolean cast(Entity entity, Node target) {
final Player player = ((Player) entity);
Item item = ((Item) target);
final Potion potion = (Potion) Consumables.getConsumableById(item.getId()).getConsumable();
final Player player = (Player) entity;
Item item = (Item) target;
player.getInterfaceManager().setViewedTab(6);
final Potion potion = (Potion) Consumables.getConsumableById(item.getId()).getConsumable();
if (potion == null) {
player.getPacketDispatch().sendMessage("You can only cast this spell on a potion.");
return false;
}
if (!item.getDefinition().isTradeable() || item.getName().toLowerCase().contains("restore") || item.getName().toLowerCase().contains("zamorak") || item.getName().toLowerCase().contains("saradomin") || item.getName().toLowerCase().contains("combat")) {
if (!item.getDefinition().isTradeable() || item.getName().toLowerCase().contains("restore") || item.getName().toLowerCase().contains("zamorak") || item.getName().toLowerCase().contains("saradomin")) {
player.getPacketDispatch().sendMessage("You can't cast this spell on that item.");
return false;
}
List<Player> pl = RegionManager.getLocalPlayers(player, 1);
int plSize = pl.size() - 1;
List<Player> pl = RegionManager.getLocalPlayers(player.getLocation(), 1);
int doses = potion.getDose(item);
if (pl.size() == 0) {
if (pl.isEmpty()) {
return false;
}
if (!super.meetsRequirements(player, true, false)) {
return false;
}
int size = 0;
for (Player players : pl) {
Player o = (Player) players;
if (size >= doses) break;
if (!o.isActive() || o.getLocks().isInteractionLocked() || o == player) {
for (Player o : pl) {
if (size >= doses) break;
if (o == player) {
continue;
}
if (!o.getSettings().isAcceptAid() && !(o instanceof AIPlayer)) {
if (!o.isActive() || o.getLocks().isInteractionLocked()) {
continue;
}
if (!o.getSettings().isAcceptAid() || o instanceof AIPlayer) {
continue;
}
o.graphics(GRAPHICS);
@ -81,17 +84,18 @@ public final class StatBoostSpell extends MagicSpell {
return false;
}
super.meetsRequirements(player, true, true);
potion.getEffect().activate(player);
playGlobalAudio(player.getLocation(), Sounds.LUNAR_STRENGTH_SHARE_2901);
player.animate(ANIMATION);
player.graphics(GRAPHICS);
player.getInventory().remove(item);
int newIndex = (potion.getIds().length - doses) + size;
if (newIndex > potion.getIds().length - 1) {
player.getInventory().add(new Item(229));
return true;
}
player.getInventory().add(new Item(potion.getIds()[newIndex]));
if (player.getInventory().remove(item)) {
potion.getEffect().activate(player);
playGlobalAudio(player.getLocation(), Sounds.LUNAR_STRENGTH_SHARE_2901);
player.animate(ANIMATION);
player.graphics(GRAPHICS);
int newIndex = (potion.getIds().length - doses) + size;
if (newIndex > potion.getIds().length - 1) {
player.getInventory().add(new Item(Items.VIAL_229));
return true;
}
player.getInventory().add(new Item(potion.getIds()[newIndex]));
}
return true;
}
}

View file

@ -16,6 +16,7 @@ import core.game.world.map.RegionManager;
import core.game.world.update.flag.context.Animation;
import core.game.world.update.flag.context.Graphics;
import core.plugin.Plugin;
import org.rs09.consts.Items;
import org.rs09.consts.Sounds;
import java.util.List;
@ -27,7 +28,7 @@ public class StatRestoreSpell extends MagicSpell {
private static final Animation ANIMATION = new Animation(4413);
private static final Graphics GRAPHICS = new Graphics(733, 130);
private static final Consumables[] acceptedPotions = new Consumables[] { Consumables.RESTORE, Consumables.SUPER_RESTO, Consumables.PRAYER, Consumables.ENERGY, Consumables.SUPER_ENERGY };
private static final Consumables[] acceptedPotions = new Consumables[] { Consumables.RESTORE, Consumables.SUPER_RESTO, Consumables.PRAYER, Consumables.ENERGY, Consumables.SUPER_ENERGY };
public StatRestoreSpell() {
super(SpellBook.LUNAR, 81, 84, null, null, null, new Item[] { new Item(Runes.ASTRAL_RUNE.getId(), 2), new Item(Runes.EARTH_RUNE.getId(), 10), new Item(Runes.WATER_RUNE.getId(), 10) });
@ -44,42 +45,38 @@ public class StatRestoreSpell extends MagicSpell {
final Player player = ((Player) entity);
Item item = ((Item) target);
player.getInterfaceManager().setViewedTab(6);
if (Consumables.getConsumableById(item.getId()) == null) {
player.getPacketDispatch().sendMessage("You can only cast this spell on a potion.");
return false;
}
if (Consumables.getConsumableById(item.getId()) == null) {
player.getPacketDispatch().sendMessage("You can only cast this spell on a potion.");
return false;
}
final Potion potion = (Potion) Consumables.getConsumableById(item.getId()).getConsumable();
if (potion == null) {
player.getPacketDispatch().sendMessage("You can only cast this spell on a potion.");
player.getPacketDispatch().sendMessage("You can only cast this spell on a potion.");
return false;
}
if (!item.getDefinition().isTradeable() || !isRestore(potion)) {
player.getPacketDispatch().sendMessage("You can't cast this spell on that item.");
return false;
}
List<Player> pl = RegionManager.getLocalPlayers(player, 2);
int plSize = pl.size() - 1;
List<Player> pl = RegionManager.getLocalPlayers(player.getLocation(), 1);
int doses = potion.getDose(item);
if (pl.size() == 0) {
return false;
}
if (!super.meetsRequirements(player, true, false)) {
return false;
}
int size = 0;
for (Player players : pl) {
if (size >= doses) break;
Player o = (Player) players;
if (!o.isActive() || o.getLocks().isInteractionLocked() || o == player) {
for (Player o : pl) {
if (size >= doses) break;
if (o == player) {
continue;
}
if (!o.isActive() || o.getLocks().isInteractionLocked()) {
continue;
}
if (!o.getSettings().isAcceptAid() && !(o instanceof AIPlayer)) {
continue;
}
o.graphics(GRAPHICS);
playGlobalAudio(o.getLocation(), Sounds.LUNAR_STAT_SHARE_INDIVIDUAL_2897);
potion.getEffect().activate(o);
size++;
}
@ -92,21 +89,22 @@ public class StatRestoreSpell extends MagicSpell {
playGlobalAudio(player.getLocation(), Sounds.LUNAR_STAT_SHARE_2899);
player.animate(ANIMATION);
player.graphics(GRAPHICS);
player.getInventory().remove(item);
int newIndex = (potion.getIds().length - doses) + size;
if (newIndex > potion.getIds().length - 1) {
player.getInventory().add(new Item(229));
return true;
}
player.getInventory().add(new Item(potion.getIds()[newIndex]));
if (player.getInventory().remove(item)) {
int newIndex = (potion.getIds().length - doses) + size;
if (newIndex > potion.getIds().length - 1) {
player.getInventory().add(new Item(Items.VIAL_229));
return true;
}
player.getInventory().add(new Item(potion.getIds()[newIndex]));
}
return true;
}
private boolean isRestore(Potion p) {
for (int i = 0; i < acceptedPotions.length; i++) {
if (p == acceptedPotions[i].getConsumable())
return true;
}
for (int i = 0; i < acceptedPotions.length; i++) {
if (p == acceptedPotions[i].getConsumable())
return true;
}
return false;
}

View file

@ -152,9 +152,9 @@ public class ForgeRegentNPC extends Familiar {
familiar.moveStep();
GroundItemManager.destroy(ground);
player.getSkills().addExperience(Skills.FIREMAKING, log.getXp() + 10);
familiar.faceLocation(object.getFaceLocation(familiar.getLocation()));
familiar.faceLocation(object.getFaceLocation(familiar.getLocation()));
SceneryBuilder.add(object, log.getLife(), FireMakingPulse.getAsh(player, log, object));
if (player.getViewport().getRegion().getId() == 10806) {
if (player.getLocation().getRegionId() == 10806) {
player.getAchievementDiaryManager().finishTask(player, DiaryType.SEERS_VILLAGE, 1, 9);
}
return true;

View file

@ -56,7 +56,7 @@ public class GiantChinchompaNPC extends Familiar {
if (!isOwnerAttackable()) {
return false;
}
final List<Entity> entitys = RegionManager.getLocalEntitys(owner, 6);
final List<Entity> entitys = RegionManager.getLocalEntities(owner.getLocation(), 6);
entitys.remove(owner);
entitys.remove(this);
sendChat("Squeak!");

View file

@ -133,7 +133,7 @@ public class PyreLordNPC extends Familiar {
player.getSkills().addExperience(Skills.FIREMAKING, log.getXp() + 10);
familiar.faceLocation(object.getFaceLocation(familiar.getLocation()));
SceneryBuilder.add(object, log.getLife(), FireMakingPulse.getAsh(player, log, object));
if (player.getViewport().getRegion().getId() == 10806) {
if (player.getLocation().getRegionId() == 10806) {
player.getAchievementDiaryManager().finishTask(player, DiaryType.SEERS_VILLAGE, 1, 9);
}
return true;

View file

@ -70,7 +70,7 @@ public class SmokeDevilNPC extends Familiar {
if (!isOwnerAttackable()) {
return false;
}
final List<Entity> entitys = RegionManager.getLocalEntitys(this, 1);
final List<Entity> entitys = RegionManager.getLocalEntities(location, 1);
entitys.remove(this);
entitys.remove(owner);
visualize(Animation.create(7820), Graphics.create(1375));

View file

@ -41,7 +41,7 @@ public class SpiritTzKihNPC extends Familiar {
@Override
protected boolean specialMove(FamiliarSpecial special) {
final List<Entity> entitys = RegionManager.getLocalEntitys(owner, 8);
final List<Entity> entitys = RegionManager.getLocalEntities(owner.getLocation(), 8);
if (entitys.size() == 0) {
return false;
}

View file

@ -72,7 +72,7 @@ public final class KittenInteractDialogue extends DialoguePlugin {
player.sendChat("Go on puss...kill that rat!");
boolean cant = true;
NPC rat = null;
for (NPC n : RegionManager.getLocalNpcs(player.getLocation(), 10)) {
for (NPC n : RegionManager.getLocalNPCs(player.getLocation(), 10)) {
if (!n.getName().contains("rat")) {
cant = false;
continue;

View file

@ -115,7 +115,7 @@ public final class StallThiefPulse extends SkillPulse<Scenery> {
SceneryBuilder.replace(node, node.transform(stall.getEmpty(node.getId())), stall.getDelay());
}
final Item item = stall.getRandomLoot();
player.getInventory().add(item);
player.getInventory().add(item);
player.getSkills().addExperience(Skills.THIEVING, stall.getExperience(), true);
if (item.getId() == 1987) {
player.getPacketDispatch().sendMessage("You steal grapes from the grape stall.");
@ -135,9 +135,9 @@ public final class StallThiefPulse extends SkillPulse<Scenery> {
if(stall == Stall.CANDLES) {
return;
}
if (type == 0) {
player.getPacketDispatch().sendMessage("You attempt to steal some " + stall.msgItem + " from the " + stall.name().toLowerCase().replace('_', ' '));
}
if (type == 0) {
player.getPacketDispatch().sendMessage("You attempt to steal some " + stall.msgItem + " from the " + stall.name().toLowerCase().replace('_', ' '));
}
}
/**
@ -156,7 +156,7 @@ public final class StallThiefPulse extends SkillPulse<Scenery> {
player.sendMessage("A higher power smites you");
return false;
}
for (NPC npc : RegionManager.getLocalNpcs(player.getLocation(), 8)) {
for (NPC npc : RegionManager.getLocalNPCs(player.getLocation(), 8)) {
if (!npc.getProperties().getCombatPulse().isAttacking() && (npc.getId() == 32 || npc.getId() == 2236)) {
npc.sendChat("Hey! Get your hands off there!");
npc.getProperties().getCombatPulse().attack(player);

View file

@ -19,6 +19,7 @@ import content.global.skill.summoning.familiar.Familiar;
import core.game.node.scenery.Scenery;
import core.game.system.task.Pulse;
import core.game.world.map.Location;
import core.game.world.map.Region;
import core.game.world.map.RegionManager;
import core.game.world.map.zone.ZoneBorders;
import core.game.world.update.flag.context.Graphics;
@ -84,37 +85,41 @@ public final class BarrowsActivityPlugin extends ActivityPlugin {
@Override
public boolean pulse() {
boolean end = true;
for (Player p : RegionManager.getRegionPlayers(14231)) {
end = false;
int index = p.getAttribute("barrow:drain-index", -1);
if (index > -1) {
p.removeAttribute("barrow:drain-index");
p.getPacketDispatch().sendItemOnInterface(-1, 1, 24, index);
continue;
}
if (p.getLocation().getZ() == 0 && p.getAttribute("barrow:looted", false) && getWorldTicks() % 3 == 0) {
if (RandomFunction.random(15) == 0) {
p.getImpactHandler().manualHit(p, RandomFunction.random(5), HitsplatType.NORMAL);
Graphics.send(Graphics.create(405), p.getLocation());
Region region = RegionManager.forId(14231);
Region.load(region);
for (int z = 0; z < 4; z++) {
for (Player p : region.assemblePlayerList(z)) {
end = false;
int index = p.getAttribute("barrow:drain-index", -1);
if (index > -1) {
p.removeAttribute("barrow:drain-index");
p.getPacketDispatch().sendItemOnInterface(-1, 1, 24, index);
continue;
}
}
int drain = 8;
if (p.getLocation().getZ() == 0 && p.getAttribute("barrow:looted", false) && getWorldTicks() % 3 == 0) {
if (RandomFunction.random(15) == 0) {
p.getImpactHandler().manualHit(p, RandomFunction.random(5), HitsplatType.NORMAL);
Graphics.send(Graphics.create(405), p.getLocation());
}
}
int drain = 8;
//if (p.getLocks().isLocked("barrow:drain") || RandomFunction.random(100) % 2 == 0) {
// continue;
//}
for (boolean killed : p.getSavedData().getActivityData().getBarrowBrothers()) {
if (killed) {
drain += 1;
//if (p.getLocks().isLocked("barrow:drain") || RandomFunction.random(100) % 2 == 0) {
// continue;
//}
for (boolean killed : p.getSavedData().getActivityData().getBarrowBrothers()) {
if (killed) {
drain += 1;
}
}
if (getWorldTicks() % 30 == 0) {
p.getSkills().decrementPrayerPoints(drain);
p.getLocks().lock("barrow:drain", (3 + RandomFunction.random(15)) * 3);
index = 1 + RandomFunction.random(6);
p.setAttribute("barrow:drain-index", index);
p.getPacketDispatch().sendItemZoomOnInterface(4761 + RandomFunction.random(12), 100, 24, index);
p.getPacketDispatch().sendAnimationInterface(9810, 24, index);
}
}
if(getWorldTicks() % 30 == 0){
p.getSkills().decrementPrayerPoints(drain);
p.getLocks().lock("barrow:drain", (3 + RandomFunction.random(15)) * 3);
index = 1 + RandomFunction.random(6);
p.setAttribute("barrow:drain-index", index);
p.getPacketDispatch().sendItemZoomOnInterface(4761 + RandomFunction.random(12), 100, 24, index);
p.getPacketDispatch().sendAnimationInterface(9810, 24, index);
}
}
return end;
@ -130,7 +135,7 @@ public final class BarrowsActivityPlugin extends ActivityPlugin {
@Override
public void locationUpdate(Entity e, Location last) {
if (e instanceof Player && e.getViewport().getRegion().getId() == 14231) {
if (e instanceof Player && e.getLocation().getRegionId() == 14231) {
boolean tunnel = false;
for (ZoneBorders border : MINI_TUNNELS) {
if (border.insideBorder(e)) {
@ -140,7 +145,7 @@ public final class BarrowsActivityPlugin extends ActivityPlugin {
}
Player player = (Player) e;
if ((getVarp(player, 1270) == 1) != tunnel) {
setVarp(player, 1270, tunnel ? 3 : 0, true);
setVarp(player, 1270, tunnel ? 3 : 0, true);
}
}
}
@ -213,7 +218,7 @@ public final class BarrowsActivityPlugin extends ActivityPlugin {
public static void shuffleCatacombs(Player player) {
int value = TUNNEL_CONFIGS[RandomFunction.random(TUNNEL_CONFIGS.length)];
value |= 1 << (6 + RandomFunction.random(4));
setVarp(player, 452, value);
setVarp(player, 452, value);
}
@Override
@ -293,10 +298,10 @@ public final class BarrowsActivityPlugin extends ActivityPlugin {
return true;
case 6774:
player.lock(1);
int brother = player.getSavedData().getActivityData().getBarrowTunnelIndex();
if (!player.getSavedData().getActivityData().getBarrowBrothers()[brother] && !player.getAttribute("brother:" + brother, false)) {
BarrowsCrypt.getCrypt(brother).spawnBrother(player, RegionManager.getTeleportLocation(target.getCenterLocation(), 4));
}
int brother = player.getSavedData().getActivityData().getBarrowTunnelIndex();
if (!player.getSavedData().getActivityData().getBarrowBrothers()[brother] && !player.getAttribute("brother:" + brother, false)) {
BarrowsCrypt.getCrypt(brother).spawnBrother(player, RegionManager.getTeleportLocation(target.getCenterLocation(), 4));
}
player.setAttribute("barrow:opened_chest", true);
sendConfiguration(player);
return true;
@ -335,7 +340,7 @@ public final class BarrowsActivityPlugin extends ActivityPlugin {
if (player.getAttribute("barrow:opened_chest", false)) {
config |= 1 << 16;
}
setVarp(player, 453, config);
setVarp(player, 453, config);
}
@Override

View file

@ -100,8 +100,9 @@ public final class TelekineticGrabSpell extends MagicSpell {
@Override
public boolean cast(final Entity entity, final Node target) {
if (!(target instanceof GroundItem))
return false;
if (!(target instanceof GroundItem)) {
return false;
}
final GroundItem ground = (GroundItem) target;
if (!canCast(entity, ground)) {
return false;
@ -131,32 +132,34 @@ public final class TelekineticGrabSpell extends MagicSpell {
Player player = entity instanceof Player ? (Player) entity : null;
GroundItem g = GroundItemManager.get(ground.getId(), ground.getLocation(), player);
if (g == null) {
player.getPacketDispatch().sendMessage("Too late!");
if (player != null) {
player.getPacketDispatch().sendMessage("Too late!");
}
return true;
}
if (g == SpecialGroundItems.AHAB_BEER.asGroundItem()){
player.getDialogueInterpreter().open(2692, new NPC(2692), true);
if (g == SpecialGroundItems.AHAB_BEER.asGroundItem()) {
if (player != null) {
player.getDialogueInterpreter().open(2692, new NPC(2692), true);
}
return true;
}
if (player == null) {
return true;
}
boolean teleZone = player.getZoneMonitor().isInZone("Telekinetic Theatre") && g.getId() == 6888;
if (player != null) {
if (g == null || !g.isActive()) {
player.getPacketDispatch().sendMessage("Too late!");
return true;
}
playAudio(player, Sounds.VULNERABILITY_IMPACT_3008);
if (!teleZone) {
player.getInventory().add(new Item(g.getId(), g.getAmount(), g.getCharge()));
} else {
TelekineticZone zone = TelekineticZone.getZone(player);
zone.moveStatue();
player.lock(getDelay());
}
player.getPacketDispatch().sendPositionedGraphics(END_GRAPHIC, ground.getLocation());
if (!g.isActive()) {
player.getPacketDispatch().sendMessage("Too late!");
return true;
}
playAudio(player, Sounds.VULNERABILITY_IMPACT_3008);
if (!teleZone) {
player.getInventory().add(new Item(g.getId(), g.getAmount(), g.getCharge()));
} else {
TelekineticZone zone = TelekineticZone.getZone(player);
zone.moveStatue();
player.lock(getDelay());
}
player.getPacketDispatch().sendPositionedGraphics(END_GRAPHIC, ground.getLocation());
if (!teleZone) {
GroundItemManager.destroy(g);
}

View file

@ -8,12 +8,9 @@ import core.game.node.entity.combat.BattleState;
import core.game.node.entity.npc.AbstractNPC;
import core.game.node.entity.npc.NPC;
import core.game.node.entity.player.Player;
import core.game.world.map.Direction;
import core.game.world.map.Location;
import core.game.world.map.RegionPlane;
import core.game.world.map.*;
import core.game.world.update.flag.context.Animation;
import core.tools.RandomFunction;
import content.minigame.pestcontrol.monsters.PCRavagerNPC;
import content.minigame.pestcontrol.monsters.PCSpinnerNPC;
/**
@ -146,8 +143,9 @@ public final class PCPortalNPC extends AbstractNPC {
public void tick() {
super.tick();
if (session != null) {
RegionPlane plane = getViewport().getCurrentPlane();
if (plane != null && session.getTicks() % 35 - plane.getPlayers().size() == 0 && plane.getNpcs().size() < 100) {
Region region = RegionManager.forId(location.getRegionId());
if ((session.getTicks() % 35 - region.assemblePlayerList(0).size()) == 0 &&
region.assembleNpcList(0).size() < 100) {
spawnNPCs();
}
if (updateLifepoints && session.getTicks() % 10 == 0) {
@ -187,9 +185,8 @@ public final class PCPortalNPC extends AbstractNPC {
int index = getDifficultyIndex();
Random r = RandomFunction.RANDOM;
int amount = index + 1;
if (getViewport().getCurrentPlane() != null) {
amount += getViewport().getCurrentPlane().getPlayers().size() / 10;
}
Region region = RegionManager.forId(location.getRegionId());
amount += region.assemblePlayerList(0).size() / 10;
if (getDifficultyIndex() == 0) {
amount += ((getDifficultyIndex() + 1) * 3) / 2;
}

View file

@ -20,6 +20,7 @@ import core.game.node.item.Item;
import core.game.system.task.Pulse;
import core.game.world.GameWorld;
import core.game.world.map.Location;
import core.game.world.map.RegionChunk;
import core.game.world.map.build.DynamicRegion;
import core.game.world.map.zone.RegionZone;
import core.game.world.map.zone.ZoneBuilder;
@ -125,40 +126,48 @@ public final class PestControlActivityPlugin extends ActivityPlugin {
if (!session.isActive()) {
return;
}
for (final Player p : session.getRegion().getPlanes()[0].getPlayers()) {
p.getProperties().setTeleportLocation(getLeaveLocation());
if (!success) {
p.getDialogueInterpreter().open(3781, true, 0, true);
// default,
// type,
// default
} else if (success && p.getAttribute("pc_zeal", 0) >= 50) {
int amount = type.ordinal() + 2;
p.getSavedData().getActivityData().increasePestPoints(amount);
Item coins = new Item(995, p.getProperties().getCurrentCombatLevel() * 10);
if (!p.getInventory().add(coins)) {
GroundItemManager.create(coins, p);
RegionChunk[][][] chunks = session.getRegion().getChunks();
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 8; y++) {
for (int z = 0; z < 4; z++) {
RegionChunk chunk = chunks[x][y][z];
for (Player p : chunk.getPlayers()) {
p.getProperties().setTeleportLocation(getLeaveLocation());
if (!success) {
p.getDialogueInterpreter().open(3781, true, 0, true);
// default,
// type,
// default
} else if (p.getAttribute("pc_zeal", 0) >= 50) {
int amount = type.ordinal() + 2;
p.getSavedData().getActivityData().increasePestPoints(amount);
Item coins = new Item(995, p.getProperties().getCurrentCombatLevel() * 10);
if (!p.getInventory().add(coins)) {
GroundItemManager.create(coins, p);
}
// default, type, name
p.getDialogueInterpreter().open(3781, true, 1, type.ordinal() == 0 ? "two" : type.ordinal() == 1 ? "three" : "four");
} else {
// default type, default
p.getDialogueInterpreter().open(3781, true, 2, true);
}
p.removeAttribute("pc_zeal");
p.removeExtension(PestControlSession.class);
p.fullRestore();
if (isPoisoned(p)) {
curePoison(p);
}
PulseManager.cancelDeathTask(p);
GameWorld.getPulser().submit(new Pulse(1, p) {
@Override
public boolean pulse() {
p.getSkills().restore();
return true;
}
});
}
}
// default, type, name
p.getDialogueInterpreter().open(3781, true, 1, type.ordinal() == 0 ? "two" : type.ordinal() == 1 ? "three" : "four");
} else {
// default type, default
p.getDialogueInterpreter().open(3781, true, 2, true);
}
p.removeAttribute("pc_zeal");
p.removeExtension(PestControlSession.class);
p.fullRestore();
if (isPoisoned(p)) {
curePoison(p);
}
PulseManager.cancelDeathTask(p);
GameWorld.getPulser().submit(new Pulse(1, p) {
@Override
public boolean pulse() {
p.getSkills().restore();
return true;
}
});
}
session.getRegion().getRegionZones().clear();
session.setActive(false);
@ -293,7 +302,7 @@ public final class PestControlActivityPlugin extends ActivityPlugin {
@Override
public boolean death(Entity e, Entity killer) {
if (e instanceof Player && e.getViewport().getRegion().getRegionId() == 10536) {
if (e instanceof Player && e.getLocation().getRegion().getRegionId() == 10536) {
PestControlSession session = e.getExtension(PestControlSession.class);
if (session != null) {
Location l = session.getRegion().getBaseLocation();

View file

@ -9,7 +9,6 @@ import core.game.node.entity.player.Player;
import core.game.node.scenery.Scenery;
import core.game.world.map.Location;
import core.game.world.map.Point;
import core.game.world.map.RegionPlane;
import core.game.world.map.build.DynamicRegion;
import core.tools.RandomFunction;
@ -21,6 +20,7 @@ import static core.api.ContentAPIKt.*;
* @author Emperor
*/
public final class PestControlSession {
private static int STRANGE_PHANTOM_OBJECT_THAT_SHARES_A_TILE_WITH_A_BARRICADE = 25636;
/**
* The barricade object offsets.
@ -31,7 +31,7 @@ public final class PestControlSession {
* The object ids of non-attackable barricades/gates.
*/
public static final int[] INVALID_OBJECT_IDS = {14230, 14231, 14232, // Barricades
14245, 14246, 14247, 14248, // Gates
14245, 14246, 14247, 14248 // Gates
};
/**
@ -123,7 +123,7 @@ public final class PestControlSession {
* @param message The message to send.
*/
public void sendMessage(String message) {
for (Player p : region.getPlanes()[0].getPlayers()) {
for (Player p : region.assemblePlayerList(0)) {
if (p.isActive()) {
p.getPacketDispatch().sendMessage(message);
}
@ -136,7 +136,7 @@ public final class PestControlSession {
* @param child The child id.
*/
public void sendString(String message, int child) {
for (Player p : region.getPlanes()[0].getPlayers()) {
for (Player p : region.assemblePlayerList(0)) {
if (p.isActive()) {
p.getPacketDispatch().sendString(message, 408, child);
}
@ -164,9 +164,9 @@ public final class PestControlSession {
* @param value The message value to send.
*/
public void sendConfig(int value) {
for (Player p : region.getPlanes()[0].getPlayers()) {
for (Player p : region.assemblePlayerList(0)) {
if (p.isActive()) {
setVarp(p, 719, value);
setVarp(p, 719, value);
}
}
}
@ -191,7 +191,7 @@ public final class PestControlSession {
message = "The red, south-western portal shield has dropped!";
break;
}
for (Player p : region.getPlanes()[0].getPlayers()) {
for (Player p : region.assemblePlayerList(0)) {
if (p.isActive()) {
p.getPacketDispatch().sendInterfaceConfig(408, 18 + (index << 1), true);
p.getPacketDispatch().sendMessage(message);
@ -233,8 +233,7 @@ public final class PestControlSession {
}
}
for (Player p : remainingPlayers)
{
for (Player p : remainingPlayers) {
int priority = p.getAttribute("pc_prior", 0) + 1;
p.getPacketDispatch().sendMessage("You have been given priority level " + priority + " over other players in joining the next");
p.getPacketDispatch().sendMessage("game.");
@ -264,7 +263,7 @@ public final class PestControlSession {
Random r = RandomFunction.RANDOM;
Location l = region.getBaseLocation();
p.getProperties().setTeleportLocation(l.transform(32 + r.nextInt(4), 49 + r.nextInt(6), 0));
setVarp(p, 1147, 0);
setVarp(p, 1147, 0);
p.getDialogueInterpreter().sendDialogues(3781, FacialExpression.FURIOUS, "You must defend the Void Knight while the portals are", "unsummoned. The ritual takes twenty minutes though,", "so you can help out by destroying them yourselves!", "Now GO GO GO!");
}
@ -272,9 +271,15 @@ public final class PestControlSession {
* Initializes the barricades list.
*/
private void initBarricadesList() {
RegionPlane p = region.getPlanes()[0];
for (Point point : OBJECT_OFFSETS) {
barricades.add(p.getObjects()[point.getX()][point.getY()]);
List<Scenery> objectList = region.assembleObjectList(0);
for (Scenery object : objectList) {
for (Point point : OBJECT_OFFSETS) {
if (object.getLocation().getLocalX() == point.getX() && object.getLocation().getLocalY() == point.getY()) {
if (object.getId() != STRANGE_PHANTOM_OBJECT_THAT_SHARES_A_TILE_WITH_A_BARRICADE) {
barricades.add(object);
}
}
}
}
}
@ -385,5 +390,4 @@ public final class PestControlSession {
public List<Scenery> getBarricades() {
return barricades;
}
}

View file

@ -29,7 +29,7 @@ public final class VoidSealPlugin extends OptionHandler {
@Override
public boolean handle(Player player, Node node, String option) {
if (player.getViewport().getRegion().getRegionId() != 10536) {
if (player.getLocation().getRegionId() != 10536) {
player.getPacketDispatch().sendMessage("You can only use the seal in Pest Control.");
return true;
}
@ -48,7 +48,7 @@ public final class VoidSealPlugin extends OptionHandler {
player.getInventory().replace(replace, item.getSlot());
}
player.graphics(Graphics.create(1177));
for (NPC npc : RegionManager.getLocalNpcs(player, 2)) {
for (NPC npc : RegionManager.getLocalNPCs(player.getLocation(), 2)) {
if (canTarget(npc)) {
npc.getImpactHandler().manualHit(player, 7 + RandomFunction.randomize(5), HitsplatType.NORMAL, 1);
npc.graphics(Graphics.create(1176));

View file

@ -7,8 +7,6 @@ import core.game.world.map.Location
import core.game.world.map.RegionManager
import core.game.world.map.path.Pathfinder
import core.tools.RandomFunction
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import content.minigame.pestcontrol.PestControlHelper.GATE_ENTRIES
import content.minigame.pestcontrol.PestControlHelper.getMyPestControlSession1
import core.game.world.GameWorld
@ -63,7 +61,7 @@ class CombatState(val bot: PestControlTestBot) {
if (portal != null) {
if(bot.location.withinDistance(portal.location,10) && portal.isActive){
val spinners = ArrayList<NPC>()
RegionManager.getLocalNpcs(bot).forEach {
RegionManager.getLocalNPCs(bot.location).forEach {
if(it.name.toLowerCase().equals("spinner") && it.location.withinDistance(bot.location,10)) spinners.add(it)
}
if(spinners.isNotEmpty()){

View file

@ -7,8 +7,6 @@ import core.game.world.map.Location
import core.game.world.map.RegionManager
import core.game.world.map.path.Pathfinder
import core.tools.RandomFunction
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import content.minigame.pestcontrol.PestControlHelper.GATE_ENTRIES
import content.minigame.pestcontrol.PestControlHelper.getMyPestControlSession2
import core.game.world.GameWorld
@ -62,7 +60,7 @@ class CombatStateIntermediate(val bot: PestControlTestBot2) {
if (portal != null) {
if(bot.location.withinDistance(portal.location,10) && portal.isActive){
val spinners = ArrayList<NPC>()
RegionManager.getLocalNpcs(bot).forEach {
RegionManager.getLocalNPCs(bot.location).forEach {
if(it.name.toLowerCase().equals("spinner") && it.location.withinDistance(bot.location,10)) spinners.add(it)
}
if(spinners.isNotEmpty()){

View file

@ -114,7 +114,7 @@ public class PCRavagerNPC extends AbstractNPC {
GameWorld.getPulser().submit(new Pulse(1, this, o) {
@Override
public boolean pulse() {
if (getViewport().getRegion().isActive() && session.getBarricades().remove(o)) {
if (getLocation().getRegion().isActive() && session.getBarricades().remove(o)) {
session.getBarricades().add(newTarget);
SceneryBuilder.replace(o, newTarget);
}
@ -173,10 +173,10 @@ public class PCRavagerNPC extends AbstractNPC {
return true;
}
@Override
public boolean shouldPreventStacking(Entity mover) {
return mover instanceof NPC;
}
@Override
public boolean shouldPreventStacking(Entity mover) {
return mover instanceof NPC;
}
@Override
public void onImpact(final Entity entity, BattleState state) {

View file

@ -100,9 +100,9 @@ public final class PCSpinnerNPC extends AbstractNPC {
*/
public void explode() {
animate(getProperties().getDeathAnimation());
for (Player p : RegionManager.getLocalPlayers(this, 1)) {
for (Player p : RegionManager.getLocalPlayers(location, 1)) {
p.getImpactHandler().manualHit(this, 5, HitsplatType.POISON);
applyPoison(p, this, 1);
applyPoison(p, this, 1);
}
GameWorld.getPulser().submit(new Pulse(1, this) {
@Override

View file

@ -75,10 +75,10 @@ public final class PCSplatterNPC extends AbstractNPC {
}
}
@Override
public boolean shouldPreventStacking(Entity mover) {
return mover instanceof NPC;
}
@Override
public boolean shouldPreventStacking(Entity mover) {
return mover instanceof NPC;
}
@Override
public void onImpact(final Entity entity, BattleState state) {
@ -132,10 +132,10 @@ public final class PCSplatterNPC extends AbstractNPC {
}
}
}
for (Player p : RegionManager.getLocalPlayers(this, 1)) {
for (Player p : RegionManager.getLocalPlayers(location, 1)) {
p.getImpactHandler().manualHit(this, RandomFunction.random(minimum, maximum), null);
}
for (NPC npc : RegionManager.getLocalNpcs(this, 1)) {
for (NPC npc : RegionManager.getLocalNPCs(location, 1)) {
if (npc != this) {
npc.getImpactHandler().manualHit(this, RandomFunction.random(minimum, maximum), null);
}

View file

@ -27,7 +27,7 @@ class ImpDefenderBehavior : NPCBehavior(6074) {
var nextCaptureTick = getAttribute(self, "next-capture-tick", 0)
if (getWorldTicks() < nextCaptureTick) return true
var players = RegionManager.getLocalPlayers(self, 2)
var players = RegionManager.getLocalPlayers(self.location, 2)
for (player in players) {
var lowestTierImpling = BNetTypes.getImpling(player)
if (lowestTierImpling == null) continue

View file

@ -1,7 +1,5 @@
package content.minigame.sorceress;
import java.util.List;
import core.game.component.Component;
import core.game.node.entity.Entity;
import core.game.node.entity.combat.CombatSwingHandler;
@ -12,6 +10,7 @@ import core.game.system.task.Pulse;
import core.game.world.GameWorld;
import core.game.world.map.Direction;
import core.game.world.map.Location;
import core.game.world.map.RegionManager;
import core.game.world.update.flag.context.Animation;
import core.game.world.update.flag.context.Graphics;
import core.net.packet.PacketRepository;
@ -194,20 +193,11 @@ public final class SorceressElementalNPC extends AbstractNPC {
return respawn;
}
/**
* Gets the tilesIndex.
* @return The tilesIndex.
*/
public int getTilesIndex() {
return tilesIndex;
}
@Override
public void tick() {
super.tick();
List<Player> players = getViewport().getCurrentPlane().getPlayers();
for (Player player : players) {
if (player == null || !player.isActive() || player.getLocks().isInteractionLocked() || DeathTask.isDead(player) || !canTeleport(player) || !CombatSwingHandler.isProjectileClipped(this, player, false)) {
for (Player player : RegionManager.getLocalPlayers(location)) {
if (!player.isActive() || player.getLocks().isInteractionLocked() || DeathTask.isDead(player) || !canTeleport(player) || !CombatSwingHandler.isProjectileClipped(this, player, false)) {
continue;
}
animate(new Animation(5803));

View file

@ -1,8 +1,6 @@
package content.minigame.vinesweeper
import BlinkinDialogue
import FarmerDialogue.Companion.FARMER_FLAG_LINES
import WinkinDialogue
import content.minigame.vinesweeper.FarmerDialogue.Companion.FARMER_FLAG_LINES
import content.minigame.vinesweeper.Vinesweeper.Companion.FARMERS
import content.minigame.vinesweeper.Vinesweeper.Companion.FARMER_CLEAR_RADIUS
import content.minigame.vinesweeper.Vinesweeper.Companion.HOLES
@ -34,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
@ -52,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))
}
@ -98,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 {
@ -115,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
}
@ -151,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."
@ -262,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
@ -274,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)
@ -334,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)
@ -347,7 +345,6 @@ class Vinesweeper : InteractionListener, InterfaceListener, MapArea {
}
}
val TUTORIAL = 685
val INSTRUCTION_SIGNS = hashMapOf(
@ -362,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++
private fun resetChunkIfBarren(chunk: RegionChunk) {
val wipedHoles = ArrayList<Scenery>()
for (x in 0 until 8) {
for (y in 0 until 8) {
for (i in 0 until 4) {
val obj = chunk.objects[x][y][i] ?: 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) {
restoreOriginalHole(scenery)
}
}
private fun countFieldState(chunk: RegionChunk, emptyHoleList: ArrayList<Scenery>, seedHoleList: ArrayList<Scenery>) {
for (x in 0 until RegionChunk.SIZE) {
for (y in 0 until RegionChunk.SIZE) {
for (i in 0 until RegionChunk.ARRAY_SIZE) {
val obj = chunk.objects[x][y][i] ?: 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 RegionChunk.SIZE) {
for (cy in 0 until RegionChunk.SIZE) {
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.")
@ -427,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!")
@ -449,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)
}
}
@ -492,10 +524,10 @@ class Vinesweeper : InteractionListener, InterfaceListener, MapArea {
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)
for (player in RegionManager.getLocalPlayers(npc.location)) {
if (player.name != dest.player.name) {
player.incrementAttribute("/save:vinesweeper:points", points / 2)
sendUpdatedPoints(player)
}
}
}
@ -507,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()
}
@ -572,21 +604,23 @@ class VinesweeperNPC : AbstractNPC {
}
override fun handleTickActions() {
val dest = seedDestinations.find { sd -> sd.loc == location }
if (locks.isMovementLocked() || locks.isInteractionLocked())
if (locks.isMovementLocked || locks.isInteractionLocked)
return
if(dest != null) {
for(npc in RegionManager.getRegionPlane(location).npcs) {
if(npc is VinesweeperNPC) {
npc.seedDestinations.remove(dest)
npc.resetWalk()
if (dest != null) {
val npcs = location.region.assembleNpcList(0)
for (npc in npcs) {
if (npc !is VinesweeperNPC || npc.seedDestinations.isEmpty() /*npc is not currently walking towards a seed*/) {
continue
}
npc.seedDestinations.remove(dest)
npc.resetWalk()
}
val scenery = getScenery(dest.loc)
if(scenery != null) {
if(id in RABBITS) {
if (scenery != null) {
if (id in RABBITS) {
handleRabbitSeed(scenery, dest)
} else {
if(dest.alive) {
if (dest.alive) {
handleFarmerFlag(scenery, dest)
} else {
handleFarmerSeed(scenery, dest)
@ -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))
@ -618,6 +652,7 @@ class VinesweeperNPC : AbstractNPC {
scheduleNPCs(dest.player, dest.loc, alive = true, rabbit = false)
}
}
fun handleFarmerSeed(scenery: Scenery, dest: Vinesweeper.SeedDestination) {
lock()
var i = 0
@ -631,7 +666,7 @@ class VinesweeperNPC : AbstractNPC {
1 -> {
animate(Animation(Animations.GNOME_FARMER_SPADE_SMACK_8732))
sendChat(FARMER_FLAG_LINES.DEAD_PLANT.line)
SceneryBuilder.replace(scenery, scenery.transform(HOLES[0]))
restoreOriginalHole(scenery)
}
2 -> {
animate(Animation(Animations.GNOME_FARMER_CLEAR_HOLES_8724))
@ -653,13 +688,13 @@ class VinesweeperNPC : AbstractNPC {
animate(Animation(Animations.GNOME_FARMER_DIG_FLAG_8725))
GameWorld.Pulser.submit(object: Pulse(3) {
override fun pulse(): Boolean {
when(i++) {
when (i++) {
0 -> {
sendChat(FARMER_FLAG_LINES.FIND_FLAG.line)
}
1 -> {
SceneryBuilder.replace(scenery, scenery.transform(HOLES[0]))
if(SEED_LOCS.contains(dest.loc)) {
restoreOriginalHole(scenery)
if (SEED_LOCS.contains(dest.loc)) {
sendChat(FARMER_FLAG_LINES.FIND_SEED.line)
animate(Animation(Animations.GNOME_FARMER_HOORAY_8731))
sendPoints(npc,dest)
@ -688,11 +723,11 @@ 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)) {
SceneryBuilder.replace(toClear, toClear.transform(HOLES[0]))
if (toClear != null && intArrayOf(Sceneries.DEAD_PLANT_29456, *NUMBERS).contains(toClear.id)) {
restoreOriginalHole(toClear)
}
}
}
@ -701,6 +736,16 @@ class VinesweeperNPC : AbstractNPC {
}
}
fun restoreOriginalHole(scenery: Scenery) {
var originalHoleId = HOLES[0]
for (obj in scenery.location.chunk.getStatObjects(scenery.location.chunkOffsetX, scenery.location.chunkOffsetY)) {
if (obj?.id != null) {
originalHoleId = obj.id
break
}
}
SceneryBuilder.replace(scenery, scenery.transform(originalHoleId))
}
/*

View file

@ -1,3 +1,5 @@
package content.minigame.vinesweeper
import core.game.component.Component
import core.game.node.item.GroundItemManager
import core.game.node.item.Item

View file

@ -126,7 +126,7 @@ public class BurthorpeTrainNPC extends AbstractNPC {
case 1061:// sergant
sendChat(MESSAGES[RandomFunction.random(MESSAGES.length)]);
delay = System.currentTimeMillis() + 9000 + RandomFunction.random(1000, 5000);
final List<NPC> soldiers = RegionManager.getLocalNpcs(this);
final List<NPC> soldiers = RegionManager.getLocalNPCs(location);
NPC soldier = null;
while (soldier == null) {
soldier = soldiers.get(RandomFunction.random(soldiers.size()));
@ -164,7 +164,7 @@ public class BurthorpeTrainNPC extends AbstractNPC {
GameWorld.getPulser().submit(new Pulse(2) {
@Override
public boolean pulse() {
final List<NPC> soldiers = RegionManager.getLocalNpcs(BurthorpeTrainNPC.this, 12);
final List<NPC> soldiers = RegionManager.getLocalNPCs(location, 12);
for (NPC n : soldiers) {
if (n.getId() != 1064) {
continue;

View file

@ -31,7 +31,6 @@ import core.plugin.Plugin;
import core.plugin.ClassScanner;
import core.tools.RandomFunction;
import kotlin.Unit;
import kotlin.jvm.functions.Function1;
import static core.api.ContentAPIKt.clearLogoutListener;
import static core.api.ContentAPIKt.registerLogoutListener;
@ -73,7 +72,7 @@ public final class CyclopesRoom extends MapZone implements Plugin<Object> {
Pathfinder.find(p.getLocation(), Location.create(2847, 3541, 2)).walk(p);
p.lock(50);
} else {
Scenery object = RegionManager.getObject(2, 2847, 3541);
Scenery object = RegionManager.getObject(2847, 3541, 2);
if (object != null && p.getLocation().getX() == 2847 && p.getLocation().getY() == 3541) {
DoorActionHandler.handleAutowalkDoor(p, object);
leave(p);

View file

@ -111,12 +111,18 @@ public final class DummyRoom extends OptionHandler {
setDelay(10);
timeStamp = GameWorld.getTicks();
dummy = RandomFunction.getRandomElement(Dummy.values());
SceneryBuilder.replace(RegionManager.getObject(dummy.getObject().getLocation()), dummy.getObject(), 11);
Scenery dummyObject = RegionManager.getObject(dummy.getObject().getLocation());
if (dummyObject != null) {
SceneryBuilder.replace(dummyObject, dummy.getObject(), 11);
}
activeDummy = true;
if (dummy == Dummy.CONTROLLED && controlled == null) {
Location l = Location.create(2860, 3551, 0);
controlled = new Scenery(dummy.getObject().getId(), l, 10, 1);
SceneryBuilder.replace(RegionManager.getObject(l), controlled, 11);
Scenery controlledObject = RegionManager.getObject(l);
if (controlledObject != null) {
SceneryBuilder.replace(controlledObject, controlled, 11);
}
}
return false;
}

View file

@ -143,7 +143,7 @@ class FaladorAchievementDiary : DiaryEventHookBase(DiaryType.FALADOR) {
)
override fun onInteracted(player: Player, event: InteractionEvent) {
when (player.viewport.region.id) {
when (player.location.regionId) {
12084 -> {
if (event.option == "burst" && event.target.id in PARTY_BALLOONS) {
finishTask(
@ -179,7 +179,7 @@ class FaladorAchievementDiary : DiaryEventHookBase(DiaryType.FALADOR) {
}
override fun onResourceProduced(player: Player, event: ResourceProducedEvent) {
when (player.viewport.region.id) {
when (player.location.regionId) {
11828 -> when (event.itemId) {
Items.YEW_LOGS_1515, Items.MAGIC_LOGS_1513 -> {
if (inBorders(player, PARK_TREE_PATCH_AREA)) {
@ -195,7 +195,7 @@ class FaladorAchievementDiary : DiaryEventHookBase(DiaryType.FALADOR) {
}
override fun onNpcKilled(player: Player, event: NPCKillEvent) {
when (player.viewport.region.id) {
when (player.location.regionId) {
11828 -> if (event.npc.id in PARK_DUCKS && inBorders(event.npc, PARK_POND_AREA)) {
finishTask(
player,

View file

@ -200,8 +200,8 @@ public class FortressGuardDialogue extends DialoguePlugin {
break;
case 54:
end();
DoorActionHandler.handleAutowalkDoor(player, RegionManager.getObject(0, 3020, 3515));
List<NPC> npcs = RegionManager.getLocalNpcs(player);
DoorActionHandler.handleAutowalkDoor(player, RegionManager.getObject(3020, 3515, 0));
List<NPC> npcs = RegionManager.getLocalNPCs(player.getLocation());
for (NPC npc : npcs) {
if (npc.getId() == 179) {
npc.getProperties().getCombatPulse().attack(player);

View file

@ -103,8 +103,8 @@ public final class GoblinVillageNPC extends AbstractNPC {
if (delay < System.currentTimeMillis() && !getProperties().getCombatPulse().isAttacking()) {
final int rand = RandomFunction.random(1, 4);
if (rand == 2) {
final List<NPC> surronding = RegionManager.getLocalNpcs(this, 10);
for (NPC n : surronding) {
final List<NPC> surrounding = RegionManager.getLocalNPCs(location, 10);
for (NPC n : surrounding) {
if (n.getId() == getId()) {
continue;
}

View file

@ -3,14 +3,14 @@ package content.region.asgarnia.goblinvillage.handlers
import core.game.interaction.IntType
import core.game.interaction.InteractionListener
import core.game.node.entity.combat.DeathTask
import core.game.world.map.RegionManager.getLocalNpcs
import core.game.world.map.RegionManager.getLocalNPCs
import org.rs09.consts.Scenery
class GoblinVillagePopulationListener : InteractionListener{
override fun defineListeners() {
on(Scenery.SIGNPOST_31301, IntType.SCENERY, "read") { player, node ->
var population = 3 // This covers General Wartface, General Bentnoze and Grubfoot
val npcs = getLocalNpcs(player, 50) // This radius covers more than the goblin village.
val npcs = getLocalNPCs(player.location, 50) // This radius covers more than the goblin village.
// There should be 18 Goblins walking around.
// 10 are within the village walls where the generals are.
// 8 of them are fighting each other on the west of the path to the village.

View file

@ -15,7 +15,7 @@ class WineOfZamorakInteraction : InteractionListener {
PickupHandler.take(player, wine as GroundItem)
return@on true
}
val npcs = RegionManager.getLocalNpcs(player)
val npcs = RegionManager.getLocalNPCs(player.location)
for (n in npcs) {
if (n.id == 188) {
n.sendChat("Hands off zamorak's wine!")

View file

@ -53,7 +53,7 @@ public final class PetshopOwnerTaverly extends DialoguePlugin {
@Override
public boolean open(Object... args) {
if (args.length > 1) {
List<NPC> npcs = RegionManager.getLocalNpcs(player);
List<NPC> npcs = RegionManager.getLocalNPCs(player.getLocation());
for (NPC n : npcs) {
if (n.getId() == 6893) {
npc = n;

View file

@ -9,6 +9,7 @@ import core.game.system.task.Pulse;
import core.game.world.GameWorld;
import core.game.world.map.Direction;
import core.game.world.map.Location;
import core.game.world.map.RegionManager;
import core.game.world.update.flag.context.Animation;
import core.game.world.update.flag.context.Graphics;
import core.net.packet.PacketRepository;
@ -123,7 +124,7 @@ public class NoraTHaggNPC extends AbstractNPC {
@Override
public void tick() {
super.tick();
List<Player> players = getViewport().getCurrentPlane().getPlayers();
List<Player> players = RegionManager.getLocalPlayers(location);
if(getLocation().getX() == 2930){
walkdir = false;
} else if(getLocation().getX() == 2904){

View file

@ -38,7 +38,7 @@ public class WitchsExperimentNPC extends AbstractNPC {
@Override
public void handleTickActions() {
super.handleTickActions();
if(!p.isActive() || !RegionManager.getLocalPlayers(this).contains(p)){
if (!p.isActive() || !RegionManager.getLocalPlayers(location).contains(p)) {
p.removeAttribute("witchs-experiment:npc_spawned");
clear();
}

View file

@ -12,6 +12,7 @@ import core.game.node.entity.combat.equipment.ArmourSet;
import core.game.node.entity.impl.Projectile;
import core.game.node.entity.impl.Animator.Priority;
import core.game.node.entity.npc.NPC;
import core.game.node.entity.player.Player;
import core.game.world.map.RegionManager;
import core.game.world.map.zone.ZoneBorders;
import core.game.world.update.flag.context.Animation;
@ -66,7 +67,7 @@ public final class GWDGraardorSwingHandler extends CombatSwingHandler {
ticks += (int) Math.ceil(entity.getLocation().getDistance(victim.getLocation()) * 0.3);
NPC npc = (NPC) entity;
List<BattleState> list = new ArrayList<>(20);
for (Entity t : RegionManager.getLocalPlayers(npc, 28)) {
for (Player t : RegionManager.getLocalPlayers(npc.getLocation(), 28)) {
if (!CHAMBER.insideBorder(t.getLocation())) {
continue;
}

View file

@ -12,6 +12,7 @@ import core.game.node.entity.combat.equipment.ArmourSet;
import core.game.node.entity.impl.Projectile;
import core.game.node.entity.impl.Animator.Priority;
import core.game.node.entity.npc.NPC;
import core.game.node.entity.player.Player;
import core.game.world.map.Direction;
import core.game.world.map.Location;
import core.game.world.map.RegionManager;
@ -83,7 +84,7 @@ public final class GWDKreeArraSwingHandler extends CombatSwingHandler {
ticks += (int) Math.ceil(entity != null ? entity.getLocation().getDistance(victim.getLocation()) : 0.0 * 0.3);
NPC npc = (NPC) entity;
List<BattleState> list = new ArrayList<>(20);
for (Entity t : RegionManager.getLocalPlayers(npc, 28)) {
for (Player t : RegionManager.getLocalPlayers(npc.getLocation(), 28)) {
if (!CHAMBER.insideBorder(t.getLocation())) {
continue;
}

View file

@ -11,6 +11,7 @@ import core.game.node.entity.combat.InteractionType;
import core.game.node.entity.combat.equipment.ArmourSet;
import core.game.node.entity.impl.Animator.Priority;
import core.game.node.entity.npc.NPC;
import core.game.node.entity.player.Player;
import core.game.world.map.RegionManager;
import core.game.world.update.flag.context.Animation;
import core.game.world.update.flag.context.Graphics;
@ -59,7 +60,7 @@ public class GWDZilyanaSwingHandler extends CombatSwingHandler {
} else {
NPC npc = (NPC) entity;
List<BattleState> list = new ArrayList<>(20);
for (Entity t : RegionManager.getLocalPlayers(npc.getCenterLocation(), (npc.size() >> 1) + 2)) {
for (Player t : RegionManager.getLocalPlayers(npc.getCenterLocation(), (npc.size() >> 1) + 2)) {
if (t.getLocation().getX() < 2908 && t.isAttackable(npc, CombatStyle.MAGIC, false)) {
list.add(new BattleState(entity, t));
}

View file

@ -61,7 +61,7 @@ public final class GodWarsNPC extends AbstractNPC {
@Override
public List<Entity> getPossibleTargets(Entity entity, int radius) {
List<Entity> targets = new ArrayList<>(20);
for (Player player : RegionManager.getLocalPlayers(entity, radius)) {
for (Player player : RegionManager.getLocalPlayers(entity.getLocation(), radius)) {
if (canSelectTarget(entity, player)) {
targets.add(player);
}
@ -69,7 +69,7 @@ public final class GodWarsNPC extends AbstractNPC {
if (!targets.isEmpty()) {
return targets;
}
for (NPC npc : RegionManager.getLocalNpcs(entity, radius)) {
for (NPC npc : RegionManager.getLocalNPCs(entity.getLocation(), radius)) {
if (canSelectTarget(entity, npc)) {
targets.add(npc);
}
@ -115,9 +115,9 @@ public final class GodWarsNPC extends AbstractNPC {
@Override
public boolean isAttackable(Entity entity, CombatStyle style, boolean message) {
if (style == CombatStyle.MELEE && faction == GodWarsFaction.ARMADYL && entity instanceof Player) {
if(message) {
((Player) entity).getPacketDispatch().sendMessage("The aviansie is flying too high for you to attack using melee.");
}
if(message) {
((Player) entity).getPacketDispatch().sendMessage("The aviansie is flying too high for you to attack using melee.");
}
return false;
}
return super.isAttackable(entity, style, message);

View file

@ -83,7 +83,7 @@ public final class GodwarsEntranceHandler extends OptionHandler {
GameWorld.getPulser().submit(new Pulse(12, player) {
@Override
public boolean pulse() {
player.getPacketDispatch().sendSceneryAnimation(RegionManager.getObject(0, 2898, 3716), Animation.create(6981));
player.getPacketDispatch().sendSceneryAnimation(RegionManager.getObject(2898, 3716, 0), Animation.create(6981));
return true;
}
});

View file

@ -49,7 +49,7 @@ class AlKharidWarriorNPC : AbstractNPC {
if (entity is Player) {
if (target == null) {
target = entity
RegionManager.getLocalNpcs(entity, supportRange).forEach {
RegionManager.getLocalNPCs(entity.location, supportRange).forEach {
if (it.id == NPCs.AL_KHARID_WARRIOR_18 && !it.properties.combatPulse.isAttacking && it != this) {
it.sendChat("Brother, I shall help thee with this infidel!")
it.attack(entity)

View file

@ -64,7 +64,7 @@ public final class LadyKeliDialogue extends DialoguePlugin {
case 60:
case 100:
npc.sendChat("You tricked me, and tied me up, Guards kill this stranger!");
List<NPC> npcc = RegionManager.getLocalNpcs(player);
List<NPC> npcc = RegionManager.getLocalNPCs(player.getLocation());
for (NPC n : npcc) {
if (n.getId() == 917) {
n.sendChat("Yes M'lady");

View file

@ -23,8 +23,7 @@ class BanditNPC(id: Int = NPCs.BANDIT_1926, location: Location? = null) : Abstra
override fun tick() {
if (!inCombat()) {
val players = RegionManager.getLocalPlayers(this, 5)
for (player in players) {
for (player in RegionManager.getLocalPlayers(location, 5)) {
if (player.inCombat()) continue
if (hasGodItem(player, God.SARADOMIN)) {
sendChat("Time to die, Saradominist filth!")
@ -47,7 +46,7 @@ class BanditNPC(id: Int = NPCs.BANDIT_1926, location: Location? = null) : Abstra
override fun onImpact(entity: Entity?, state: BattleState?) {
if (entity is Player) {
RegionManager.getLocalNpcs(entity, supportRange).forEach {
RegionManager.getLocalNPCs(entity.location, supportRange).forEach {
if (it.id == NPCs.BANDIT_1926 && !it.properties.combatPulse.isAttacking && it != this) {
it.sendChat("You picked the wrong place to start trouble!")
it.attack(entity)

View file

@ -47,7 +47,7 @@ public final class BedabinPlugin extends OptionHandler {
player.getPacketDispatch().sendMessage("You walk back out the tent.");
break;
}
player.getDialogueInterpreter().open(834, RegionManager.getNpc(player, 834));
player.getDialogueInterpreter().open(834, RegionManager.getNpc(player.getLocation(), 834, 16));
break;
}
break;

View file

@ -211,7 +211,7 @@ public final class KalphiteQueenNPC extends AbstractNPC {
*/
private BattleState[] getRangeTargets(Entity e, Entity victim) {
List<BattleState> list = new ArrayList<>(20);
for (Entity t : RegionManager.getLocalPlayers(victim, -1 + (int) e.getCenterLocation().getDistance(victim.getLocation()))) {
for (Player t : RegionManager.getLocalPlayers(victim.getLocation(), -1 + (int) e.getCenterLocation().getDistance(victim.getLocation()))) {
if (t.isAttackable(e, CombatStyle.RANGE, false)) {
list.add(new BattleState(e, t));
}
@ -315,12 +315,10 @@ public final class KalphiteQueenNPC extends AbstractNPC {
return;
}
if (style == CombatStyle.MAGIC) {
BattleState[] states = new BattleState[entity.getViewport().getCurrentPlane().getPlayers().size() + 1];
List<Player> localPlayers = RegionManager.getLocalPlayers(entity.getLocation());
BattleState[] states = new BattleState[localPlayers.size() + 1];
int index = 1;
if (states.length == 0) {
return;
}
for (Player p : entity.getViewport().getCurrentPlane().getPlayers()) {
for (Player p : localPlayers) {
if (p != victim) {
states[index++] = new BattleState(entity, p);
}

View file

@ -80,7 +80,7 @@ public final class KhardianInteractionPlugin extends OptionHandler {
if (!failed) {
player.getSkills().addExperience(Skills.WOODCUTTING, 10, true);
}
SceneryBuilder.replace(((Scenery) node), new Scenery(DRY_CACTUS, node.getLocation()), SPAWN_DELAY + RandomFunction.random(RegionManager.getLocalPlayers(player).size() / 2));
SceneryBuilder.replace(((Scenery) node), new Scenery(DRY_CACTUS, node.getLocation()), SPAWN_DELAY + RandomFunction.random(RegionManager.getLocalPlayers(player.getLocation()).size() / 2));
break;
}
return true;

View file

@ -108,7 +108,7 @@ public final class AnaDialogue extends DialoguePlugin {
case 3:
player.getInventory().add(TouristTrap.WROUGHT_IRON_KEY, player);
player.getPacketDispatch().sendMessage("Ana spots Irena and waves...");
NPC irena = RegionManager.getNpc(player, 4986);
NPC irena = RegionManager.getNpc(player.getLocation(), 4986, 16);
irena.sendChat("Hi Ana!");
quest.setStage(player, 98);
end();

View file

@ -307,8 +307,8 @@ public final class DesertGuardDialogue extends DialoguePlugin {
* Method used to warn players whom are breaking rules.
*/
private void warn() {
final List<Player> players = RegionManager.getLocalPlayers(this);
for (final Player player : players) {
final List<Player> players = RegionManager.getLocalPlayers(location);
for (Player player : players) {
if (player.getAttribute("guard-warning", 0) > GameWorld.getTicks() || !player.getZoneMonitor().isInZone("mining camp") || player.inCombat() || !player.getLocation().withinDistance(this.getLocation(), 8)) {
continue;
}

View file

@ -201,7 +201,7 @@ public final class TouristTrapPlugin extends OptionHandler {
GameWorld.getPulser().submit(new Pulse(2, player) {
@Override
public boolean pulse() {
player.getDialogueInterpreter().open(831, RegionManager.getNpc(player, 831));
player.getDialogueInterpreter().open(831, RegionManager.getNpc(player.getLocation(), 831, 16));
return true;
}
});
@ -1254,7 +1254,7 @@ public final class TouristTrapPlugin extends OptionHandler {
@Override
public boolean handle(NodeUsageEvent event) {
final Player player = event.getPlayer();
player.getDialogueInterpreter().open(831, RegionManager.getNpc(player, 831));
player.getDialogueInterpreter().open(831, RegionManager.getNpc(player.getLocation(), 831, 16));
return true;
}

View file

@ -167,7 +167,7 @@ class FremennikAchievementDiary : DiaryEventHookBase(DiaryType.FREMENNIK) {
}
override fun onResourceProduced(player: Player, event: ResourceProducedEvent) {
when (player.viewport.region.id) {
when (player.location.regionId) {
10553 -> if (event.source.id in FISHING_SPOTS) {
finishTask(
player,
@ -204,7 +204,7 @@ class FremennikAchievementDiary : DiaryEventHookBase(DiaryType.FREMENNIK) {
}
override fun onNpcKilled(player: Player, event: NPCKillEvent) {
when (player.viewport.region.id) {
when (player.location.regionId) {
10042, 10554 -> if (event.npc.id in ROCK_CRABS) {
progressIncrementalTask(
player,
@ -260,7 +260,7 @@ class FremennikAchievementDiary : DiaryEventHookBase(DiaryType.FREMENNIK) {
}
override fun onPickedUp(player: Player, event: PickUpEvent) {
when (player.viewport.region.id) {
when (player.location.regionId) {
10810 -> if (event.itemId == Items.SEAWEED_401) {
progressIncrementalTask(
player,
@ -284,7 +284,7 @@ class FremennikAchievementDiary : DiaryEventHookBase(DiaryType.FREMENNIK) {
}
override fun onSummoningPointsRecharged(player: Player, event: SummoningPointsRechargeEvent) {
when (player.viewport.region.id) {
when (player.location.regionId) {
10552 -> if (event.obelisk.id == Scenery.SMALL_OBELISK_29944) {
finishTask(
player,
@ -296,7 +296,7 @@ class FremennikAchievementDiary : DiaryEventHookBase(DiaryType.FREMENNIK) {
}
override fun onInteracted(player: Player, event: InteractionEvent) {
when (player.viewport.region.id) {
when (player.location.regionId) {
10811 -> if (event.target.id == Scenery.COLLAPSED_TRAP_19233 && inBorders(player, RELLEKKA_HUNTING_AREA) && event.option == "dismantle") {
finishTask(
player,

View file

@ -8,8 +8,6 @@ import core.game.node.entity.player.Player
import core.game.node.entity.player.link.diary.DiaryType
import core.game.node.entity.player.link.music.MusicEntry
import core.game.node.entity.skill.Skills
import content.global.skill.gather.woodcutting.WoodcuttingSkillPulse
import core.game.node.scenery.Scenery
import core.game.system.task.Pulse
import core.game.world.map.Location
import core.game.world.map.RegionManager
@ -23,6 +21,8 @@ import core.game.system.config.ItemConfigParser
import core.game.world.GameWorld.Pulser
import content.data.Quests
import core.game.interaction.QueueStrength
import core.game.node.Node
import org.rs09.consts.Scenery
class TFTInteractionListeners : InteractionListener {
@ -74,7 +74,7 @@ class TFTInteractionListeners : InteractionListener {
removeItem(player,LOW_ALC_KEG)
setAttribute(player,"/save:fremtrials:keg-mixed", true)
sendMessage(player,"The cherry bomb in the pipe goes off.")
RegionManager.getLocalEntitys(player).stream().forEach { e -> e.sendChat("What was THAT??") }
RegionManager.getLocalNPCs(player.location).stream().forEach { e -> e.sendChat("What was THAT??") }
sendMessage(player,"You mix the kegs together.")
} else {
player.dialogueInterpreter?.sendDialogue("I can't do this right now. I should create","a distraction.")
@ -204,7 +204,7 @@ class TFTInteractionListeners : InteractionListener {
setAttribute(player,"/save:fremtrials:maze-complete",true)
DestRoom(2662, 10034, 2668, 10039).getCenter()
}
else -> getRandomLocation(player)
else -> getRandomLocation(player, portal)
}
return@on true
}
@ -280,17 +280,15 @@ class TFTInteractionListeners : InteractionListener {
return Location((swx + nex) / 2, (swy + ney) / 2).transform(1,0,0)
}
fun getRandomLocation(player: Player?): Location{
var obj: Scenery? = null
while(obj?.id != 5138) {
val objects = player?.viewport?.chunks?.random()?.random()?.objects
obj = objects?.random()?.random()
if(obj == null || obj.location?.equals(Location(0,0,0))!!){
continue
fun getRandomLocation(player: Player, portal: Node): Location {
val objects = player.location.region.assembleObjectList(player.location.z)
objects.shuffle()
for (o in objects) {
if (o.id == Scenery.PORTAL_5138) {
return o.location
}
}
return obj.location
return portal.location
}
fun hasEquippableItems(player: Player?): Boolean {

View file

@ -70,7 +70,7 @@ public final class DagannothKingNPC extends AbstractNPC {
state.setEstimatedHit(RandomFunction.random(type.getMaxHit() - 5, type.getMaxHit()));
}
if (type != DagType.REX && RandomFunction.random(5) <= 2) {
List<Player> players = RegionManager.getLocalPlayers(this, 9);
List<Player> players = RegionManager.getLocalPlayers(location, 9);
if (players.size() <= 1) {
return;
}

View file

@ -17,6 +17,7 @@ import core.game.node.entity.combat.CombatStyle;
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.item.GroundItemManager;
import core.game.node.scenery.SceneryBuilder;
import core.game.system.task.Pulse;
import core.game.world.GameWorld;
@ -71,7 +72,7 @@ public final class WaterBirthDungeonZone extends MapZone implements Plugin<Objec
public boolean move(Entity e, Location from, Location to) {
for (Location location : DOOR_SUPPORTS) {
if (location.equals(to)) {
List<NPC> npcs = RegionManager.getLocalNpcs(location, 0);
List<NPC> npcs = RegionManager.getLocalNPCs(location, 0);
NPC npc = null;
if (npcs.size() != 0) {
npc = npcs.get(0);
@ -243,10 +244,10 @@ public final class WaterBirthDungeonZone extends MapZone implements Plugin<Objec
* allows both players and pet rocks to activate the pad
*/
private boolean pressurePadActivated(Player player, Location location) {
if (RegionManager.getLocalPlayers(location,0).size() > 0) {
if (!RegionManager.getLocalPlayers(location, 0).isEmpty()) {
return true;
}
if (RegionManager.getRegionPlane(location).getItem(Items.PET_ROCK_3695,location,player) != null) {
if (GroundItemManager.get(Items.PET_ROCK_3695, location, player) != null) {
return true;
}
return false;
@ -411,9 +412,9 @@ public final class WaterBirthDungeonZone extends MapZone implements Plugin<Objec
if (entity.getLocation().getDistance(getLocation()) <= 3) {
if (entity instanceof Player) {
Player player = entity.asPlayer();
if(message) {
player.sendMessage("The door is propped securely shut from this side...");
}
if(message) {
player.sendMessage("The door is propped securely shut from this side...");
}
}
return false;
}

View file

@ -188,7 +188,7 @@ public class SilkMerchantPlugin extends DialoguePlugin {
npc = (NPC) args[0];
if (player.getSavedData().getGlobalData().getSilkSteal() > System.currentTimeMillis()) {
end();
for (NPC npc : RegionManager.getLocalNpcs(player.getLocation(), 8)) {
for (NPC npc : RegionManager.getLocalNPCs(player.getLocation(), 8)) {
if (!npc.getProperties().getCombatPulse().isAttacking() && npc.getId() == 32) {
npc.sendChat("Hey! Get your hands off there!");
npc.getProperties().getCombatPulse().attack(player);

Some files were not shown because too many files have changed in this diff Show more