mirror of
https://gitlab.com/2009scape/2009scape.git
synced 2026-08-25 20:35:10 -06:00
Hopefully last review comments for greg
This commit is contained in:
parent
f2456b676f
commit
33f1ea94d1
28 changed files with 206 additions and 208 deletions
|
|
@ -16,7 +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;
|
||||
import static core.game.node.entity.combat.MultihitTargetsKt.findMultihitTargetsForD2h;
|
||||
|
||||
/**
|
||||
* Handles the Powerstab special attack.
|
||||
|
|
@ -73,7 +73,7 @@ public final class PowerstabSpecialHandler extends MeleeSwingHandler implements
|
|||
if (!multi) {
|
||||
return super.swing(entity, victim, state);
|
||||
}
|
||||
List<Entity> list = findMultihitTargets(entity.getLocation(), entity, CombatStyle.MELEE);
|
||||
List<Entity> list = findMultihitTargetsForD2h(entity.getLocation(), entity, CombatStyle.MELEE);
|
||||
BattleState[] targets = new BattleState[list.size()];
|
||||
int count = 0;
|
||||
for (Entity e : list) {
|
||||
|
|
|
|||
|
|
@ -26,14 +26,12 @@ 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.
|
||||
*/
|
||||
|
|
@ -98,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())];
|
||||
|
|
@ -261,7 +258,7 @@ public final class HouseManager {
|
|||
*/
|
||||
public void expelGuests(Player player) {
|
||||
if (isLoaded()) {
|
||||
for (int z = 0; z < 4; z++) {
|
||||
for (int z = 0; z < Region.PLANES; z++) {
|
||||
ArrayList<Player> players = new ArrayList<>(houseRegion.assemblePlayerList(z));
|
||||
if (dungeonRegion != null) {
|
||||
players.addAll(dungeonRegion.assemblePlayerList(z));
|
||||
|
|
@ -292,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -308,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);
|
||||
|
|
@ -325,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;
|
||||
}
|
||||
}
|
||||
|
|
@ -368,7 +365,7 @@ 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.setBuild(true);
|
||||
|
|
@ -604,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;
|
||||
|
|
@ -699,9 +696,6 @@ public final class HouseManager {
|
|||
* 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());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ public final class Room {
|
|||
}
|
||||
}
|
||||
}
|
||||
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()) {
|
||||
|
|
|
|||
|
|
@ -214,11 +214,11 @@ class WoodcuttingListener : InteractionListener {
|
|||
player.animate(SkillingTool.getHatchet(player).animation)
|
||||
val playersAroundMe: List<Player> = RegionManager.getLocalPlayers(player.location, 2)
|
||||
.stream()
|
||||
.filter { p -> p.name != player.name }
|
||||
.filter { p -> p != player }
|
||||
.toList()
|
||||
val soundIndex = RandomFunction.random(0, woodcuttingSounds.size)
|
||||
for (player in playersAroundMe) {
|
||||
playAudio(player, woodcuttingSounds[soundIndex])
|
||||
for (p in playersAroundMe) {
|
||||
playAudio(p, woodcuttingSounds[soundIndex])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ public final class AncientTeleportPlugin extends MagicSpell {
|
|||
return false;
|
||||
}
|
||||
homeTeleport((Player) entity, Location.create(3087, 3495, 0));
|
||||
entity.dispatch(new SpellCastEvent(SpellBook.ANCIENT, getSpellId(), target));
|
||||
entity.dispatch(new SpellCastEvent(SpellBook.ANCIENT, getSpellId(), target));
|
||||
} else if (entity.getTeleporter().send(location.transform(0, RandomFunction.random(3), 0), TeleportType.ANCIENT)) {
|
||||
if (!super.meetsRequirements(entity, true, true)) {
|
||||
entity.getTeleporter().getCurrentTeleport().stop();
|
||||
|
|
|
|||
|
|
@ -17,8 +17,6 @@ import static core.api.ContentAPIKt.getAttribute;
|
|||
*/
|
||||
@Initializable
|
||||
public final class DraynorBankGuard extends DialoguePlugin {
|
||||
private final static String HAS_SEEN_RECORDING = "draynor-recording";
|
||||
|
||||
/**
|
||||
* Represents the coins item needed to re-watch the recording.
|
||||
*/
|
||||
|
|
@ -58,7 +56,7 @@ public final class DraynorBankGuard extends DialoguePlugin {
|
|||
public boolean handle(int interfaceId, int buttonId) {
|
||||
switch (stage) {
|
||||
case 0:
|
||||
if (!getAttribute(player, HAS_SEEN_RECORDING, false)) {
|
||||
if (!getAttribute(player, DBRCutscene.HAS_SEEN_RECORDING, false)) {
|
||||
interpreter.sendOptions("Select an option", "Can I deposit my stuff here?", "That wall doesn't look very good.", "Sorry, I don't want anything.");
|
||||
stage = 1;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ class ScriptAPI(private val bot: Player) {
|
|||
*/
|
||||
fun getNearestNodeFromList(acceptedNames: List<String>, isObject: Boolean): Node? {
|
||||
val region = RegionManager.forId(bot.location.regionId)
|
||||
val list = if (isObject) region.assembleObjectList(bot.location.z) else region.assembleEntityList(bot.location.z)
|
||||
val list = if (isObject) region.assembleObjectList(bot.location.z) else region.assembleNodeList(bot.location.z)
|
||||
return processEvaluationList(list, acceptedName = acceptedNames)
|
||||
}
|
||||
|
||||
|
|
@ -147,7 +147,7 @@ class ScriptAPI(private val bot: Player) {
|
|||
*/
|
||||
fun getNearestNode(id: Int, isObject: Boolean): Node? {
|
||||
val region = RegionManager.forId(bot.location.regionId)
|
||||
val list = if (isObject) region.assembleObjectList(bot.location.z) else region.assembleEntityList(bot.location.z)
|
||||
val list = if (isObject) region.assembleObjectList(bot.location.z) else region.assembleNodeList(bot.location.z)
|
||||
return processEvaluationList(list, acceptedId = id)
|
||||
}
|
||||
|
||||
|
|
@ -159,7 +159,7 @@ class ScriptAPI(private val bot: Player) {
|
|||
*/
|
||||
fun getNearestNode(entityName: String): Node? {
|
||||
val region = RegionManager.forId(bot.location.regionId)
|
||||
val list = region.assembleEntityList(bot.location.z)
|
||||
val list = region.assembleNodeList(bot.location.z)
|
||||
return processEvaluationList(list, acceptedName = listOf(entityName))
|
||||
}
|
||||
|
||||
|
|
@ -172,7 +172,7 @@ class ScriptAPI(private val bot: Player) {
|
|||
*/
|
||||
fun getNearestNode(name: String, isObject: Boolean): Node? {
|
||||
val region = RegionManager.forId(bot.location.regionId)
|
||||
val list = region.assembleEntityList(bot.location.z)
|
||||
val list = region.assembleNodeList(bot.location.z)
|
||||
return processEvaluationList(list, acceptedName = listOf(name))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -240,7 +240,7 @@ public abstract class MovementPulse extends Pulse {
|
|||
private boolean tryInteract() {
|
||||
Location ml = mover.getLocation();
|
||||
// Allow being within 1 square of moving entities to interact with them.
|
||||
int radius = destination instanceof Entity && ((Entity)destination).getWalkingQueue().hasPath() ? 1 : 0;
|
||||
int radius = destination instanceof Entity && ((Entity) destination).getWalkingQueue().hasPath() ? 1 : 0;
|
||||
if (interactLocation == null)
|
||||
return false;
|
||||
boolean atInteractLocation = Math.max(Math.abs(ml.getX() - interactLocation.getX()), Math.abs(ml.getY() - interactLocation.getY())) <= radius;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,12 @@ private fun isAttackable(victim: Entity, attacker: Entity, combatStyle: CombatSt
|
|||
|
||||
fun findMultihitTargets(center: Location, attacker: Entity, combatStyle: CombatStyle?): List<Entity> {
|
||||
val targets = getLocalEntities(center, 1).filter { it != attacker && isAttackable(it, attacker, combatStyle, false) }
|
||||
return targets.take(9)
|
||||
return targets.take(9) //https://runescape.wiki/w/Vesta%27s_spear "the opponent and up to 9 additional targets in a 3x3 area around the player"; https://oldschool.runescape.wiki/w/Ice_Barrage "up to nine targets"
|
||||
}
|
||||
|
||||
fun findMultihitTargetsForD2h(center: Location, attacker: Entity, combatStyle: CombatStyle?): List<Entity> {
|
||||
val targets = getLocalEntities(center, 1).filter { it != attacker && isAttackable(it, attacker, combatStyle, false) }
|
||||
return targets.filter { it.location.withinDistance(center, 1) } .take(14) //runescape.wiki/w/Dragon_2h_sword?oldid=859949 "up to 14 enemies in the squares around the player (Only directly in front of and to the sides, it does not attack those diagonal of the player)"
|
||||
}
|
||||
|
||||
fun findMultihitTargetsForChinchompa(center: Location, attacker: Entity, victim: Entity): List<Entity> {
|
||||
|
|
@ -50,5 +55,5 @@ fun findMultihitTargetsForChinchompa(center: Location, attacker: Entity, victim:
|
|||
}
|
||||
targets = targetCandidates.filter { it is NPC || isOwnerOf(it, npcs) }
|
||||
}
|
||||
return targets.take(9)
|
||||
}
|
||||
return targets.take(9) //https://runescape.wiki/w/Chinchompa "up to 9 enemies"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -856,7 +856,7 @@ public class Player extends Entity {
|
|||
getZoneMonitor().getZones().clear();
|
||||
playerFlags.setLastSceneGraph(null);
|
||||
playerFlags.setUpdateSceneGraph(false);
|
||||
playerFlags.setLastViewport(new RegionChunk[13][13]);
|
||||
playerFlags.setLastViewport(new RegionChunk[MapChunkRenderer.BUILD_AREA_SIZE][MapChunkRenderer.BUILD_AREA_SIZE]);
|
||||
renderInfo.getLocalNPCs().clear();
|
||||
renderInfo.getLocalPlayers().clear();
|
||||
renderInfo.setLastLocation(null);
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ class SpawnCommandSet : CommandSet(Privilege.ADMIN){
|
|||
if (args.size != 1) reject(player, "::removeobject doesn't support arguments")
|
||||
val obj = getObject(player.location)
|
||||
if (obj == null) {
|
||||
sendMessage(player, "All ten objects on the tile were null.")
|
||||
sendMessage(player, "All four objects on the tile were null.")
|
||||
return@define
|
||||
}
|
||||
sendMessage(player, "The first object found on the tile was ${obj.id}; it will now be removed.")
|
||||
|
|
@ -161,12 +161,10 @@ class SpawnCommandSet : CommandSet(Privilege.ADMIN){
|
|||
define("objects", Privilege.STANDARD, "::objects", "Prints a list of all ten sceneries at your current coordinates") { player, args ->
|
||||
if (args.size != 1) reject(player, "::objects doesn't support arguments")
|
||||
val chunk = getRegionChunk(player.location)
|
||||
val region = RegionManager.forId(player.location.regionId)
|
||||
fun dump(label: String, objects: List<Scenery?>) {
|
||||
sendMessage(player, "--- $label ---")
|
||||
val nulls = ArrayList<Int>(10)
|
||||
for (i in 0 until objects.size) {
|
||||
val o = objects[i]
|
||||
for ((i, o) in objects.withIndex()) {
|
||||
if (o == null) {
|
||||
nulls.add(i)
|
||||
} else {
|
||||
|
|
@ -174,7 +172,7 @@ class SpawnCommandSet : CommandSet(Privilege.ADMIN){
|
|||
val r = if (o.isRenderable) "R" else ""
|
||||
val a = if (o.isActive) "A" else ""
|
||||
var props = c + r + a
|
||||
if (props.length > 0) {
|
||||
if (props.isNotEmpty()) {
|
||||
props = " *$props"
|
||||
}
|
||||
sendMessage(player, " $i: $o$props")
|
||||
|
|
|
|||
|
|
@ -34,8 +34,8 @@ class ConfigParser : Commands {
|
|||
fun reloadConfigs(callback: () -> Unit) {
|
||||
GlobalScope.launch {
|
||||
RegionManager.apply { r ->
|
||||
r.addScenery.clear()
|
||||
r.removeScenery.clear()
|
||||
r.addSceneries.clear()
|
||||
r.removeSceneries.clear()
|
||||
}
|
||||
|
||||
Repository.npcs.toTypedArray().forEach { npc ->
|
||||
|
|
|
|||
|
|
@ -45,8 +45,8 @@ class ObjectOverrideParser {
|
|||
val obj = Scenery(id, loc, type, rotation)
|
||||
val region = RegionManager.forId(loc.regionId)
|
||||
when (mode) {
|
||||
"remove" -> region.removeScenery.add(obj) //type and rotation are currently ignored, but this can be changed in Region.java if needed
|
||||
"add" -> region.addScenery.add(obj)
|
||||
"remove" -> region.removeSceneries.add(obj) //type and rotation are currently ignored, but this can be changed in Region.java if needed
|
||||
"add" -> region.addSceneries.add(obj)
|
||||
else -> log(this::class.java, Log.ERR, "Ignored unknown ObjectOverride mode $mode!")
|
||||
}
|
||||
count++
|
||||
|
|
|
|||
|
|
@ -32,6 +32,21 @@ import static core.api.ContentAPIKt.log;
|
|||
* @author Emperor
|
||||
*/
|
||||
public class Region {
|
||||
/**
|
||||
* The number of tiles per region.
|
||||
*/
|
||||
public static final int SIZE = 64;
|
||||
|
||||
/**
|
||||
* The number of chunks per region.
|
||||
*/
|
||||
public static final int CHUNKS_SIZE = 8;
|
||||
|
||||
/**
|
||||
* The number of z levels per x,y coordinate.
|
||||
*/
|
||||
public static final int PLANES = 4;
|
||||
|
||||
/**
|
||||
* The region x-coordinate.
|
||||
*/
|
||||
|
|
@ -45,7 +60,7 @@ public class Region {
|
|||
/**
|
||||
* The chunks in this region.
|
||||
*/
|
||||
protected RegionChunk[][][] chunks = new RegionChunk[8][8][4];
|
||||
protected RegionChunk[][][] chunks = new RegionChunk[CHUNKS_SIZE][CHUNKS_SIZE][PLANES];
|
||||
|
||||
/**
|
||||
* The activity pulse.
|
||||
|
|
@ -105,8 +120,8 @@ public class Region {
|
|||
/**
|
||||
* Any scenery overrides for this region
|
||||
*/
|
||||
private ArrayList<Scenery> addScenery = new ArrayList<>();
|
||||
private ArrayList<Scenery> removeScenery = new ArrayList<>();
|
||||
private final ArrayList<Scenery> addSceneries = new ArrayList<>();
|
||||
private final ArrayList<Scenery> removeSceneries = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Constructs a new {@code Region} {@code Object}.
|
||||
|
|
@ -117,10 +132,10 @@ public class Region {
|
|||
this.x = x;
|
||||
this.y = y;
|
||||
Location swCorner = getBaseLocation();
|
||||
for (x = 0; x < 8; x++) {
|
||||
for (y = 0; y < 8; y++) {
|
||||
for (int z = 0; z < 4; z++) {
|
||||
Location loc = swCorner.transform(x*8, y*8, z);
|
||||
for (x = 0; x < CHUNKS_SIZE; x++) {
|
||||
for (y = 0; y < CHUNKS_SIZE; y++) {
|
||||
for (int z = 0; z < PLANES; z++) {
|
||||
Location loc = swCorner.transform(x*RegionChunk.SIZE, y*RegionChunk.SIZE, z);
|
||||
chunks[x][y][z] = new RegionChunk(loc, 0);
|
||||
}
|
||||
}
|
||||
|
|
@ -157,9 +172,9 @@ public class Region {
|
|||
*/
|
||||
public void add(RegionZone zone) {
|
||||
regionZones.add(zone);
|
||||
for (int x = 0; x < 8; x++) {
|
||||
for (int y = 0; y < 8; y++) {
|
||||
for (int z = 0; z < 4; z++) {
|
||||
for (int x = 0; x < CHUNKS_SIZE; x++) {
|
||||
for (int y = 0; y < CHUNKS_SIZE; y++) {
|
||||
for (int z = 0; z < PLANES; z++) {
|
||||
for (NPC npc : chunks[x][y][z].getNpcs()) {
|
||||
npc.getZoneMonitor().updateLocation(npc.getLocation());
|
||||
}
|
||||
|
|
@ -175,9 +190,9 @@ public class Region {
|
|||
|
||||
public void remove(RegionZone zone) {
|
||||
regionZones.remove(zone);
|
||||
for (int x = 0; x < 8; x++) {
|
||||
for (int y = 0; y < 8; y++) {
|
||||
for (int z = 0; z < 4; z++) {
|
||||
for (int x = 0; x < CHUNKS_SIZE; x++) {
|
||||
for (int y = 0; y < CHUNKS_SIZE; y++) {
|
||||
for (int z = 0; z < PLANES; z++) {
|
||||
for (NPC npc : chunks[x][y][z].getNpcs()) {
|
||||
npc.getZoneMonitor().updateLocation(npc.getLocation());
|
||||
}
|
||||
|
|
@ -213,9 +228,9 @@ public class Region {
|
|||
if (isViewed()) {
|
||||
return false;
|
||||
}
|
||||
for (int x = 0; x < 8; x++) {
|
||||
for (int y = 0; y < 8; y++) {
|
||||
for (int z = 0; z < 4; z++) {
|
||||
for (int x = 0; x < CHUNKS_SIZE; x++) {
|
||||
for (int y = 0; y < CHUNKS_SIZE; y++) {
|
||||
for (int z = 0; z < PLANES; z++) {
|
||||
if (!chunks[x][y][z].getPlayers().isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -240,9 +255,9 @@ public class Region {
|
|||
if (!active) {
|
||||
active = true;
|
||||
load(this);
|
||||
for (int x = 0; x < 8; x++) {
|
||||
for (int y = 0; y < 8; y++) {
|
||||
for (int z = 0; z < 4; z++) {
|
||||
for (int x = 0; x < CHUNKS_SIZE; x++) {
|
||||
for (int y = 0; y < CHUNKS_SIZE; y++) {
|
||||
for (int z = 0; z < PLANES; z++) {
|
||||
for (NPC npc : chunks[x][y][z].getNpcs()) {
|
||||
if (npc.isActive()) {
|
||||
Repository.addRenderableNPC(npc);
|
||||
|
|
@ -300,11 +315,11 @@ public class Region {
|
|||
return;
|
||||
}
|
||||
|
||||
byte[][][] mapscapeData = new byte[4][64][64];
|
||||
for (int x = 0; x < 8; x++) {
|
||||
for (int y = 0; y < 8; y++) {
|
||||
for (int z = 0; z < 4; z++) {
|
||||
r.chunks[x][y][z].getFlags().setLandscape(new boolean[8][8]);
|
||||
byte[][][] mapscapeData = new byte[PLANES][SIZE][SIZE];
|
||||
for (int x = 0; x < CHUNKS_SIZE; x++) {
|
||||
for (int y = 0; y < CHUNKS_SIZE; y++) {
|
||||
for (int z = 0; z < PLANES; z++) {
|
||||
r.chunks[x][y][z].getFlags().setLandscape(new boolean[RegionChunk.SIZE][RegionChunk.SIZE]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -328,14 +343,14 @@ public class Region {
|
|||
}
|
||||
}
|
||||
MapscapeParser.clipMapscape(r, r.chunks, mapscapeData);
|
||||
for (Scenery object : r.removeScenery) {
|
||||
for (Scenery object : r.removeSceneries) {
|
||||
// Get the actual object, not the instance that's kept in the removeScenery array
|
||||
Scenery realObject = RegionManager.getObject(object.getLocation()); //can be extended to take into account type and rotation if needed
|
||||
if (realObject != null) {
|
||||
SceneryBuilder.remove(realObject);
|
||||
}
|
||||
}
|
||||
for (Scenery object : r.addScenery) {
|
||||
for (Scenery object : r.addSceneries) {
|
||||
SceneryBuilder.add(object);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
|
|
@ -353,20 +368,20 @@ public class Region {
|
|||
r.flagActive();
|
||||
return false;
|
||||
}
|
||||
for (int x = 0; x < 8; x++) {
|
||||
for (int y = 0; y < 8; y++) {
|
||||
for (int z = 0; z < 4; z++) {
|
||||
for (int x = 0; x < CHUNKS_SIZE; x++) {
|
||||
for (int y = 0; y < CHUNKS_SIZE; y++) {
|
||||
for (int z = 0; z < PLANES; z++) {
|
||||
if (!force && !chunks[x][y][z].getPlayers().isEmpty()) {
|
||||
log(CommunicationInfo.class, Log.ERR, "Players still in region!");
|
||||
log(CommunicationInfo.class, Log.ERR, "Players still in region! (region id " + getId() + "; " + chunks[x][y][z].getPlayers().size() + " players on a chunk)");
|
||||
r.flagActive();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int x = 0; x < 8; x++) {
|
||||
for (int y = 0; y < 8; y++) {
|
||||
for (int z = 0; z < 4; z++) {
|
||||
for (int x = 0; x < CHUNKS_SIZE; x++) {
|
||||
for (int y = 0; y < CHUNKS_SIZE; y++) {
|
||||
for (int z = 0; z < PLANES; z++) {
|
||||
if (!(r instanceof DynamicRegion)) {
|
||||
for (NPC npc : chunks[x][y][z].getNpcs()) {
|
||||
npc.onRegionInactivity();
|
||||
|
|
@ -552,12 +567,12 @@ public class Region {
|
|||
|
||||
public List<Scenery> assembleObjectList(int z) {
|
||||
ArrayList<Scenery> list = new ArrayList<>();
|
||||
for (int x = 0; x < 8; x++) {
|
||||
for (int y = 0; y < 8; y++) {
|
||||
for (int x = 0; x < CHUNKS_SIZE; x++) {
|
||||
for (int y = 0; y < CHUNKS_SIZE; y++) {
|
||||
RegionChunk chunk = chunks[x][y][z];
|
||||
for (int offsetX = 0; offsetX < 8; offsetX++) {
|
||||
for (int offsetY = 0; offsetY < 8; offsetY++) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int offsetX = 0; offsetX < RegionChunk.SIZE; offsetX++) {
|
||||
for (int offsetY = 0; offsetY < RegionChunk.SIZE; offsetY++) {
|
||||
for (int i = 0; i < RegionChunk.ARRAY_SIZE; i++) {
|
||||
Scenery object = chunk.getObjects()[offsetX][offsetY][i];
|
||||
if (object != null) {
|
||||
list.add(object);
|
||||
|
|
@ -572,8 +587,8 @@ public class Region {
|
|||
|
||||
public List<NPC> assembleNpcList(int z) {
|
||||
ArrayList<NPC> list = new ArrayList<>();
|
||||
for (int x = 0; x < 8; x++) {
|
||||
for (int y = 0; y < 8; y++) {
|
||||
for (int x = 0; x < CHUNKS_SIZE; x++) {
|
||||
for (int y = 0; y < CHUNKS_SIZE; y++) {
|
||||
RegionChunk chunk = chunks[x][y][z];
|
||||
list.addAll(chunk.getNpcs());
|
||||
}
|
||||
|
|
@ -583,8 +598,8 @@ public class Region {
|
|||
|
||||
public List<Player> assemblePlayerList(int z) {
|
||||
ArrayList<Player> list = new ArrayList<>();
|
||||
for (int x = 0; x < 8; x++) {
|
||||
for (int y = 0; y < 8; y++) {
|
||||
for (int x = 0; x < CHUNKS_SIZE; x++) {
|
||||
for (int y = 0; y < CHUNKS_SIZE; y++) {
|
||||
RegionChunk chunk = chunks[x][y][z];
|
||||
list.addAll(chunk.getPlayers());
|
||||
}
|
||||
|
|
@ -592,7 +607,7 @@ public class Region {
|
|||
return list;
|
||||
}
|
||||
|
||||
public List<Node> assembleEntityList(int z) {
|
||||
public List<Node> assembleNodeList(int z) {
|
||||
ArrayList<Node> list = new ArrayList<>(assembleObjectList(z));
|
||||
list.addAll(assemblePlayerList(z));
|
||||
list.addAll(assembleNpcList(z));
|
||||
|
|
@ -601,7 +616,6 @@ public class Region {
|
|||
|
||||
/**
|
||||
* Getter for region aggro tolerances.
|
||||
* @return
|
||||
*/
|
||||
public HashMap<String, Long> getTolerances() {
|
||||
return tolerances;
|
||||
|
|
@ -610,10 +624,10 @@ public class Region {
|
|||
/**
|
||||
* Getters for addScenery and removeScenery.
|
||||
*/
|
||||
public ArrayList<Scenery> getAddScenery() {
|
||||
return addScenery;
|
||||
public ArrayList<Scenery> getAddSceneries() {
|
||||
return addSceneries;
|
||||
}
|
||||
public ArrayList<Scenery> getRemoveScenery() {
|
||||
return removeScenery;
|
||||
public ArrayList<Scenery> getRemoveSceneries() {
|
||||
return removeSceneries;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import core.game.world.map.build.DynamicRegion;
|
|||
import core.game.world.map.build.LandscapeParser;
|
||||
import core.game.world.update.flag.UpdateFlag;
|
||||
import core.net.packet.IoBuffer;
|
||||
import org.rs09.consts.Items;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
|
@ -188,22 +189,21 @@ public class RegionChunk {
|
|||
* Adds the scenery to the static and dynamic object lists. You never want this unless you are the landscape-parsing
|
||||
* code.
|
||||
* @param object The object to add.
|
||||
* @return The slot it was added into.
|
||||
*/
|
||||
public int addStatDyn(Scenery object, int chunkOffsetX, int chunkOffsetY) {
|
||||
public void addStatDyn(Scenery object, int chunkOffsetX, int chunkOffsetY) {
|
||||
for (int i = 0; i < ARRAY_SIZE; i++) {
|
||||
Scenery current = statObjects[chunkOffsetX][chunkOffsetY][i];
|
||||
if (current == null) {
|
||||
statObjects[chunkOffsetX][chunkOffsetY][i] = object;
|
||||
objects[chunkOffsetX][chunkOffsetY][i] = object.transform(object.getId()); //deep copy so that active/renderable flags don't synchronize across multiple copies of e.g. a POH
|
||||
return i;
|
||||
return;
|
||||
}
|
||||
if (current.getId() == object.getId()) {
|
||||
// It's possible that we already have this object. One instance of this was found at 1906, 5082, 0,
|
||||
// where our cache has more than one copy of the same [Scenery 15349, [1906, 5082, 0], type=22, rot=1]
|
||||
// object. Since authentically, the engine can only support one of the same type of object per tile,
|
||||
// if the ID matches we can be confident that this is a duplicate.
|
||||
return i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("RC addStatDyn insufficient array length for storing object " + object);
|
||||
|
|
@ -249,8 +249,7 @@ public class RegionChunk {
|
|||
*/
|
||||
public void addPlayer(Player player) {
|
||||
players.add(player);
|
||||
Region region = getCurrentBase().getRegion();
|
||||
region.flagActive();
|
||||
currentBase.getRegion().flagActive();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -282,8 +281,7 @@ public class RegionChunk {
|
|||
*/
|
||||
public void removePlayer(Player player) {
|
||||
players.remove(player);
|
||||
Region region = getCurrentBase().getRegion();
|
||||
region.checkInactive();
|
||||
currentBase.getRegion().checkInactive();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -318,8 +316,8 @@ public class RegionChunk {
|
|||
*/
|
||||
public List<Scenery> assembleObjectList() {
|
||||
ArrayList<Scenery> list = new ArrayList<>(ARRAY_SIZE);
|
||||
for (int offsetX = 0; offsetX < 8; offsetX++) {
|
||||
for (int offsetY = 0; offsetY < 8; offsetY++) {
|
||||
for (int offsetX = 0; offsetX < SIZE; offsetX++) {
|
||||
for (int offsetY = 0; offsetY < SIZE; offsetY++) {
|
||||
for (int i = 0; i < ARRAY_SIZE; i++) {
|
||||
Scenery object = objects[offsetX][offsetY][i];
|
||||
if (object != null) {
|
||||
|
|
@ -331,12 +329,6 @@ public class RegionChunk {
|
|||
return list;
|
||||
}
|
||||
|
||||
public List<Node> getEntities() {
|
||||
List<Node> entities = new ArrayList<>(assembleObjectList());
|
||||
entities.addAll(npcs);
|
||||
return entities;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the players.
|
||||
* @return The players.
|
||||
|
|
@ -424,7 +416,7 @@ public class RegionChunk {
|
|||
}
|
||||
|
||||
public ArrayList<GroundItem> drawItems(List<GroundItem> items, Player player) {
|
||||
ArrayList<GroundItem> totalItems = items != null ? new ArrayList<GroundItem>(items) : new ArrayList<GroundItem>();
|
||||
ArrayList<GroundItem> totalItems = items != null ? new ArrayList<>(items) : new ArrayList<GroundItem>();
|
||||
|
||||
if (player.getAttribute("chunkdraw", false)) {
|
||||
Location l = currentBase;
|
||||
|
|
@ -436,7 +428,7 @@ public class RegionChunk {
|
|||
else if (x == 0 || x == SIZE - 1)
|
||||
add = true;
|
||||
if (add)
|
||||
totalItems.add(new GroundItem(new Item(13444), l.transform(x, y, 0), player));
|
||||
totalItems.add(new GroundItem(new Item(Items.ABYSSAL_WHIP_13444), l.transform(x, y, 0), player));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -461,7 +453,7 @@ public class RegionChunk {
|
|||
add = true;
|
||||
|
||||
if (add)
|
||||
totalItems.add(new GroundItem(new Item(13444), l.transform(x,y,0), player));
|
||||
totalItems.add(new GroundItem(new Item(Items.ABYSSAL_WHIP_13444), l.transform(x,y,0), player));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -502,7 +494,7 @@ public class RegionChunk {
|
|||
*/
|
||||
public List<GroundItem> getItems() {
|
||||
if (items == null) {
|
||||
items = new ArrayList<GroundItem>();
|
||||
items = new ArrayList<>();
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
|
@ -555,7 +547,7 @@ public class RegionChunk {
|
|||
* Gets the objects index for the given object id and/or scenery type.
|
||||
* @param x The x-coordinate on the region chunk.
|
||||
* @param y The y-coordinate on the region chunk.
|
||||
* @param objectId The object id.
|
||||
* @param objectId The object id. -1 if any.
|
||||
* @param type The scenery type.
|
||||
*/
|
||||
public int getIndex(int x, int y, int objectId, int type) {
|
||||
|
|
@ -569,7 +561,6 @@ public class RegionChunk {
|
|||
return i;
|
||||
} else {
|
||||
if (o.getId() == objectId) {
|
||||
// TODO: what if there are multiple instances of the same object? Hopefully this is only a theoretical possibility in this game
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
|
@ -654,8 +645,8 @@ public class RegionChunk {
|
|||
* @param from The region plane to get the new clipping flags from.
|
||||
*/
|
||||
public void rebuildClippingFlags(RegionChunk from) {
|
||||
for (int x = 0; x < 8; x++) {
|
||||
for (int y = 0; y < 8; y++) {
|
||||
for (int x = 0; x < SIZE; x++) {
|
||||
for (int y = 0; y < SIZE; y++) {
|
||||
// Import the landscape flags from the template chunk to the new chunk
|
||||
flags.getLandscape()[x][y] = from.getFlags().getLandscape()[x][y];
|
||||
projectileFlags.getLandscape()[x][y] = from.getProjectileFlags().getLandscape()[x][y];
|
||||
|
|
@ -670,6 +661,15 @@ public class RegionChunk {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotation consts. Greg loves these :)
|
||||
*/
|
||||
private static int NORTH_ROTATION = 0;
|
||||
private static int EAST_ROTATION = 1;
|
||||
private static int SOUTH_ROTATION = 2;
|
||||
private static int WEST_ROTATION = 2;
|
||||
private static int NUMBER_OF_CARDINAL_ROTATIONS = 4;
|
||||
|
||||
/**
|
||||
* Rotates the chunk.
|
||||
* @param direction The direction.
|
||||
|
|
@ -692,22 +692,22 @@ public class RegionChunk {
|
|||
}
|
||||
}
|
||||
clear();
|
||||
switch(direction) {
|
||||
case NORTH: rotation = 0; break;
|
||||
case EAST: rotation = 1; break;
|
||||
case SOUTH: rotation = 2; break;
|
||||
case WEST: rotation = 3; break;
|
||||
default: rotation = (direction.toInteger() + (direction.toInteger() % 2 == 0 ? 2 : 0)) % 4;
|
||||
switch (direction) {
|
||||
case NORTH: rotation = NORTH_ROTATION; break;
|
||||
case EAST: rotation = EAST_ROTATION; break;
|
||||
case SOUTH: rotation = SOUTH_ROTATION; break;
|
||||
case WEST: rotation = WEST_ROTATION; break;
|
||||
default: rotation = (direction.toInteger() + (direction.toInteger() % 2 == 0 ? 2 : 0)) % NUMBER_OF_CARDINAL_ROTATIONS;
|
||||
log(this.getClass(), Log.ERR, "Attempted to rotate a chunk in a non-cardinal direction - using fallback rotation code. This should be investigated!");
|
||||
break;
|
||||
};
|
||||
for (int i = 0; i < ARRAY_SIZE; i++) {
|
||||
for (int x = 0; x < SIZE; x++) {
|
||||
for (int y = 0; y < SIZE; y++) {
|
||||
for (int x = 0; x < SIZE; x++) {
|
||||
for (int y = 0; y < SIZE; y++) {
|
||||
for (int i = 0; i < ARRAY_SIZE; i++) {
|
||||
Scenery object = copy[x][y][i];
|
||||
if (object != null) {
|
||||
int[] pos = getRotatedPosition(x, y, object.getDefinition().getSizeX(), object.getDefinition().getSizeY(), object.getRotation(), rotation);
|
||||
Scenery obj = object.transform(object.getId(), (object.getRotation() + rotation) % 4, object.getLocation().transform(pos[0] - x, pos[1] - y, 0));
|
||||
Scenery obj = object.transform(object.getId(), (object.getRotation() + rotation) % NUMBER_OF_CARDINAL_ROTATIONS, object.getLocation().transform(pos[0] - x, pos[1] - y, 0));
|
||||
if (object instanceof Constructed) {
|
||||
obj = obj.asConstructed();
|
||||
}
|
||||
|
|
@ -740,12 +740,12 @@ public class RegionChunk {
|
|||
return new int[] { x, y };
|
||||
}
|
||||
if (chunkRotation == 1) {
|
||||
return new int[] { y, 7 - x - (sizeX - 1) };
|
||||
return new int[] { y, (SIZE-1) - x - (sizeX - 1) };
|
||||
}
|
||||
if (chunkRotation == 2) {
|
||||
return new int[] { 7 - x - (sizeX - 1), 7 - y - (sizeY - 1) };
|
||||
return new int[] { (SIZE-1) - x - (sizeX - 1), 7 - y - (sizeY - 1) };
|
||||
}
|
||||
return new int[] { 7 - y - (sizeY - 1), x };
|
||||
return new int[] { (SIZE-1) - y - (sizeY - 1), x };
|
||||
}
|
||||
|
||||
public ChunkFlags getFlags() {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ object RegionManager {
|
|||
@JvmStatic val CLIPPING_FLAGS = HashMap<Int, Array<Int>>()
|
||||
@JvmStatic val PROJECTILE_FLAGS = HashMap<Int, Array<Int>>()
|
||||
|
||||
val LOCK = ReentrantLock()
|
||||
private val LOCK = ReentrantLock()
|
||||
|
||||
/**
|
||||
* Gets the region for the given region id.
|
||||
|
|
@ -378,12 +378,10 @@ object RegionManager {
|
|||
}
|
||||
}
|
||||
is NPC -> {
|
||||
if (src != null) {
|
||||
src.chunk.remove(entity)
|
||||
}
|
||||
src?.chunk?.remove(entity)
|
||||
dst.chunk.add(entity)
|
||||
}
|
||||
else -> throw IllegalStateException("Tried to move an Entity that was neither Player nor NPC")
|
||||
else -> log(this::class.java, Log.ERR, "Tried to move an Entity that was neither Player nor NPC, but $entity of class ${entity.javaClass}! It tried to move from $src to $dst.")
|
||||
}
|
||||
}
|
||||
entity.zoneMonitor.updateLocation(entity.walkingQueue.footPrint)
|
||||
|
|
@ -393,7 +391,6 @@ object RegionManager {
|
|||
* Gets local entities. You never call the below function directly (it's inlined); instead, you use one of the typed helpers defined directly below this function.
|
||||
* @param location the location.
|
||||
* @param distance the distance.
|
||||
* @param maximum the maximum number of entities to return.
|
||||
* @return the list.
|
||||
*/
|
||||
private inline fun<reified T: Entity> getLocalEntitiesOfType(location: Location, distance: Int): List<T> {
|
||||
|
|
@ -402,10 +399,10 @@ object RegionManager {
|
|||
for (cy in (location.absChunkY - 8)..(location.absChunkY + 8)) {
|
||||
val chunk = Location(cx shl 3, cy shl 3, location.z).chunk
|
||||
if (T::class.java.isAssignableFrom(Player::class.java)) {
|
||||
entities.addAll(chunk.players as Collection<T>)
|
||||
entities.addAll(chunk.players.filterIsInstance<T>())
|
||||
}
|
||||
if (T::class.java.isAssignableFrom(NPC::class.java)) {
|
||||
entities.addAll(chunk.npcs as Collection<T>)
|
||||
entities.addAll(chunk.npcs.filterIsInstance<T>())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ import java.util.ArrayList;
|
|||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* Represents a dynamically constructed region.
|
||||
*
|
||||
|
|
@ -69,9 +68,9 @@ public final class DynamicRegion extends Region {
|
|||
super(x, y);
|
||||
this.regionId = regionId;
|
||||
// Reset any stale flags at this region's chunk coordinates
|
||||
for (int chunkX = 0; chunkX < 8; chunkX++) {
|
||||
for (int chunkY = 0; chunkY < 8; chunkY++) {
|
||||
for (int cz = 0; cz < 4; cz++) {
|
||||
for (int chunkX = 0; chunkX < CHUNKS_SIZE; chunkX++) {
|
||||
for (int chunkY = 0; chunkY < CHUNKS_SIZE; chunkY++) {
|
||||
for (int cz = 0; cz < Region.PLANES; cz++) {
|
||||
RegionChunk chunk = chunks[chunkX][chunkY][cz];
|
||||
for (int chunkOffsetX = 0; chunkOffsetX < 8; chunkOffsetX++) {
|
||||
for (int chunkOffsetY = 0; chunkOffsetY < 8; chunkOffsetY++) {
|
||||
|
|
@ -98,7 +97,7 @@ public final class DynamicRegion extends Region {
|
|||
public static DynamicRegion create(int regionId) {
|
||||
int x = (regionId >> 8) << 6;
|
||||
int y = (regionId & 0xFF) << 6;
|
||||
return create(new ZoneBorders(x, y, x + 64, y + 64))[0];
|
||||
return create(new ZoneBorders(x, y, x + SIZE, y + SIZE))[0];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -112,7 +111,7 @@ public final class DynamicRegion extends Region {
|
|||
int y = (regionOne & 0xFF) << 6;
|
||||
int x1 = (regionTwo >> 8) << 6;
|
||||
int y1 = (regionTwo & 0xFF) << 6;
|
||||
return create(new ZoneBorders(x, y, x1 + 64, y1 + 64))[0];
|
||||
return create(new ZoneBorders(x, y, x1 + SIZE, y1 + SIZE))[0];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -123,7 +122,6 @@ public final class DynamicRegion extends Region {
|
|||
public static DynamicRegion[] create(ZoneBorders copy) {
|
||||
int baseX = copy.getSouthWestX() >> 6;
|
||||
int baseY = copy.getSouthWestY() >> 6;
|
||||
|
||||
ZoneBorders border = findZoneBorders((copy.getNorthEastX() - copy.getSouthWestX()) >> 3, (copy.getNorthEastY() - copy.getSouthWestY()) >> 3);
|
||||
RESERVED_AREAS.add(border);
|
||||
Location l = Location.create(border.getSouthWestX(), border.getSouthWestY(), 0);
|
||||
|
|
@ -139,7 +137,7 @@ public final class DynamicRegion extends Region {
|
|||
}
|
||||
}
|
||||
for (Region r : regions) {
|
||||
for (int z = 0; z < 4; z++) {
|
||||
for (int z = 0; z < PLANES; z++) {
|
||||
for (Player player : r.assemblePlayerList(z)) {
|
||||
if (player != null) {
|
||||
player.updateSceneGraph(false);
|
||||
|
|
@ -174,11 +172,11 @@ public final class DynamicRegion extends Region {
|
|||
int count = 0;
|
||||
int width = (sizeX >> 3) << 6;
|
||||
int height = (sizeY >> 3) << 6;
|
||||
if (width < 64) {
|
||||
width = 64;
|
||||
if (width < SIZE) {
|
||||
width = SIZE;
|
||||
}
|
||||
if (height < 64) {
|
||||
height = 64;
|
||||
if (height < SIZE) {
|
||||
height = SIZE;
|
||||
}
|
||||
while (true) {
|
||||
int endX = x + width;
|
||||
|
|
@ -195,10 +193,10 @@ public final class DynamicRegion extends Region {
|
|||
return new ZoneBorders(x, y, endX, endY);
|
||||
}
|
||||
if (++count % 15 == 0) {
|
||||
y += 64;
|
||||
y += SIZE;
|
||||
x = 0;
|
||||
} else {
|
||||
x += 64;
|
||||
x += SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -219,7 +217,7 @@ public final class DynamicRegion extends Region {
|
|||
for (int offsetY = 0; offsetY < 8; offsetY++) {
|
||||
int x = regionX + (offsetX << 3);
|
||||
int y = regionY + (offsetY << 3);
|
||||
for (int plane = 0; plane < 4; plane++) {
|
||||
for (int plane = 0; plane < PLANES; plane++) {
|
||||
RegionChunk c = base.getChunks()[offsetX][offsetY][plane];
|
||||
if (c == null) {
|
||||
c = new RegionChunk(Location.create(0, 0, 0), 0);
|
||||
|
|
@ -319,9 +317,9 @@ public final class DynamicRegion extends Region {
|
|||
if (!super.flagInactive(force)) {
|
||||
return false;
|
||||
}
|
||||
for (int x = 0; x < 8; x++) {
|
||||
for (int y = 0; y < 8; y++) {
|
||||
for (int z = 0; z < 4; z++) {
|
||||
for (int x = 0; x < CHUNKS_SIZE; x++) {
|
||||
for (int y = 0; y < CHUNKS_SIZE; y++) {
|
||||
for (int z = 0; z < PLANES; z++) {
|
||||
RegionChunk chunk = chunks[x][y][z];
|
||||
for (NPC npc : chunk.getNpcs()) {
|
||||
npc.clear();
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ public final class MapscapeParser {
|
|||
}
|
||||
// The cache is packed by region, so we need to parse it along the local-x/y coordinates
|
||||
for (int z = 0; z < 4; z++) {
|
||||
for (int localX = 0; localX < 64; localX++) {
|
||||
for (int localY = 0; localY < 64; localY++) {
|
||||
for (int localX = 0; localX < Region.SIZE; localX++) {
|
||||
for (int localY = 0; localY < Region.SIZE; localY++) {
|
||||
int chunkX = localX >> 3;
|
||||
int chunkY = localY >> 3;
|
||||
int chunkOffsetX = localX & 7;
|
||||
|
|
@ -33,7 +33,7 @@ public final class MapscapeParser {
|
|||
boolean[][] landscape;
|
||||
if (chunk == null) {
|
||||
// Still need to consume the buffer data even for null chunks
|
||||
landscape = new boolean[8][8];
|
||||
landscape = new boolean[RegionChunk.SIZE][RegionChunk.SIZE];
|
||||
} else {
|
||||
landscape = chunk.getFlags().getLandscape();
|
||||
}
|
||||
|
|
@ -71,15 +71,15 @@ public final class MapscapeParser {
|
|||
* @param mapscape The mapscape.
|
||||
*/
|
||||
public static void clipMapscape(Region r, RegionChunk[][][] chunks, byte[][][] mapscape) {
|
||||
for (int z = 0; z < 4; z++) {
|
||||
for (int chunkX = 0; chunkX < 8; chunkX++) {
|
||||
for (int chunkY = 0; chunkY < 8; chunkY++) {
|
||||
for (int z = 0; z < Region.PLANES; z++) {
|
||||
for (int chunkX = 0; chunkX < RegionChunk.SIZE; chunkX++) {
|
||||
for (int chunkY = 0; chunkY < RegionChunk.SIZE; chunkY++) {
|
||||
RegionChunk chunk = chunks[chunkX][chunkY][z];
|
||||
for (int x = 0; x < 8; x++) {
|
||||
for (int y = 0; y < 8; y++) {
|
||||
for (int x = 0; x < RegionChunk.SIZE; x++) {
|
||||
for (int y = 0; y < RegionChunk.SIZE; y++) {
|
||||
chunk.getFlags().flagEmptyTile(x, y);
|
||||
int chunkOffsetX = chunkX*8 + x;
|
||||
int chunkOffsetY = chunkY*8 + y;
|
||||
int chunkOffsetX = chunkX*RegionChunk.SIZE + x;
|
||||
int chunkOffsetY = chunkY*RegionChunk.SIZE + y;
|
||||
if ((mapscape[z][chunkOffsetX][chunkOffsetY] & 0x1) == 1) {
|
||||
int plane = z;
|
||||
if ((mapscape[1][chunkOffsetX][chunkOffsetY] & 0x2) == 2) {
|
||||
|
|
|
|||
|
|
@ -64,11 +64,6 @@ public class ModeratorZone extends MapZone {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean interact(Entity entity, Node target, Option option) {
|
||||
return super.interact(entity, target, option);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure() {
|
||||
register(new ZoneBorders(2840, 5204, 2853, 5224));
|
||||
|
|
|
|||
|
|
@ -1,7 +1,22 @@
|
|||
package core.game.world.update
|
||||
|
||||
import core.game.world.map.RegionChunk
|
||||
import java.util.Collections
|
||||
import java.util.IdentityHashMap
|
||||
|
||||
object ChunkUpdateTracker : ChunkDirtyListener {
|
||||
private val dirty = Collections.newSetFromMap(IdentityHashMap<RegionChunk, Boolean>())
|
||||
|
||||
override fun onFlagged(chunk: RegionChunk) {
|
||||
dirty.add(chunk)
|
||||
}
|
||||
|
||||
/** Resets flags on exactly the chunks flagged this tick. Must run after all per-player flushes. */
|
||||
fun resetAll() {
|
||||
dirty.forEach { it.resetUpdateFlags() }
|
||||
dirty.clear()
|
||||
}
|
||||
}
|
||||
fun interface ChunkDirtyListener {
|
||||
fun onFlagged(chunk: RegionChunk)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
package core.game.world.update
|
||||
|
||||
import core.game.world.map.RegionChunk
|
||||
import java.util.Collections
|
||||
import java.util.IdentityHashMap
|
||||
|
||||
object ChunkUpdateTracker : ChunkDirtyListener {
|
||||
private val dirty = Collections.newSetFromMap(IdentityHashMap<RegionChunk, Boolean>())
|
||||
|
||||
override fun onFlagged(chunk: RegionChunk) {
|
||||
dirty.add(chunk)
|
||||
}
|
||||
|
||||
/** Resets flags on exactly the chunks flagged this tick. Must run after all per-player flushes. */
|
||||
fun resetAll() {
|
||||
dirty.forEach { it.resetUpdateFlags() }
|
||||
dirty.clear()
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,6 @@ package core.game.world.update
|
|||
import core.game.node.entity.player.Player
|
||||
import core.game.world.map.Location
|
||||
import core.game.world.map.RegionChunk
|
||||
import core.game.world.map.build.DynamicRegion
|
||||
import core.net.packet.PacketRepository
|
||||
import core.net.packet.context.ClearChunkContext
|
||||
import core.net.packet.out.ClearRegionChunk
|
||||
|
|
@ -14,7 +13,8 @@ import java.util.*
|
|||
* @author Emperor
|
||||
*/
|
||||
object MapChunkRenderer {
|
||||
const val buildAreaDepth = 6
|
||||
const val BUILD_AREA_DEPTH = 6
|
||||
const val BUILD_AREA_SIZE = 2*BUILD_AREA_DEPTH + 1
|
||||
|
||||
/**
|
||||
* Sends the map chunk rendering packet.
|
||||
|
|
@ -23,8 +23,8 @@ object MapChunkRenderer {
|
|||
@JvmStatic
|
||||
fun render(player: Player) {
|
||||
val last = player.playerFlags.lastViewport
|
||||
val updated: MutableList<RegionChunk> = ArrayList()
|
||||
val current: MutableList<MutableList<RegionChunk>> = ArrayList()
|
||||
val updated: ArrayList<RegionChunk> = ArrayList()
|
||||
val current: ArrayList<MutableList<RegionChunk>> = ArrayList()
|
||||
|
||||
// Center the build area on the loaded scene anchor (lastSceneGraph), NOT the live player position.
|
||||
// The client's 13x13 build area is anchored at lastSceneGraph; addressing chunks relative to it keeps
|
||||
|
|
@ -33,9 +33,9 @@ object MapChunkRenderer {
|
|||
// pushes the viewport edge to drift+6 chunks from the anchor, off-window, so edge items never render.
|
||||
val anchor = player.playerFlags.lastSceneGraph ?: player.location
|
||||
val center = Location.create(anchor.x, anchor.y, player.location.z)
|
||||
for (dcx in -buildAreaDepth..+buildAreaDepth) {
|
||||
for (dcx in -BUILD_AREA_DEPTH..BUILD_AREA_DEPTH) {
|
||||
val addX = ArrayList<RegionChunk>()
|
||||
for (dcy in -buildAreaDepth..+buildAreaDepth) {
|
||||
for (dcy in -BUILD_AREA_DEPTH..BUILD_AREA_DEPTH) {
|
||||
val newloc = center.transform(dcx * 8, dcy * 8, 0)
|
||||
addX.add(newloc.chunk)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import core.game.world.map.RegionManager
|
|||
import core.net.packet.IoBuffer
|
||||
import core.net.packet.PacketHeader
|
||||
import core.game.world.GameWorld
|
||||
import core.game.world.map.MapDistance
|
||||
import java.nio.ByteBuffer
|
||||
import java.util.*
|
||||
|
||||
|
|
@ -30,7 +31,7 @@ object NPCRenderer {
|
|||
val it: Iterator<NPC> = localNPCs.iterator()
|
||||
while (it.hasNext()) {
|
||||
val npc = it.next()
|
||||
val withinDistance = player.location.withinDistance(npc.location, 15)
|
||||
val withinDistance = player.location.withinDistance(npc.location, MapDistance.RENDERING.distance)
|
||||
if (npc.isHidden(player) || !withinDistance || npc.properties.isTeleporting) {
|
||||
buffer.putBits(1, 1).putBits(2, 3)
|
||||
toRemove.add(npc)
|
||||
|
|
@ -51,7 +52,7 @@ object NPCRenderer {
|
|||
}
|
||||
}
|
||||
localNPCs.removeAll(toRemove)
|
||||
for (npc in RegionManager.getLocalNPCs(player.location, 15)) {
|
||||
for (npc in RegionManager.getLocalNPCs(player.location, MapDistance.RENDERING.distance)) {
|
||||
if (localNPCs.size >= 255) {
|
||||
break
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package core.game.world.update.flag;
|
|||
|
||||
import core.game.world.map.Location;
|
||||
import core.game.world.map.RegionChunk;
|
||||
import core.game.world.update.MapChunkRenderer;
|
||||
|
||||
/**
|
||||
* A class holding a player's updating flags.
|
||||
|
|
@ -17,7 +18,7 @@ public final class PlayerFlags {
|
|||
/**
|
||||
* The last viewport.
|
||||
*/
|
||||
private RegionChunk[][] lastViewport = new RegionChunk[13][13];
|
||||
private RegionChunk[][] lastViewport = new RegionChunk[MapChunkRenderer.BUILD_AREA_SIZE][MapChunkRenderer.BUILD_AREA_SIZE];
|
||||
|
||||
/**
|
||||
* The location the player was standing on when last scene graph update
|
||||
|
|
|
|||
|
|
@ -69,4 +69,4 @@ class SnowStormHolidayRandomNPC : HolidayRandomEventNPC(NPCs.SNOW_6740) {
|
|||
|
||||
override fun talkTo(npc: NPC) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ import core.game.world.map.Region;
|
|||
import core.game.world.map.RegionChunk;
|
||||
import core.game.world.map.RegionManager;
|
||||
import core.game.world.map.build.DynamicRegion;
|
||||
import core.game.world.update.MapChunkRenderer;
|
||||
import core.net.packet.IoBuffer;
|
||||
import core.net.packet.OutgoingPacket;
|
||||
import core.net.packet.PacketHeader;
|
||||
|
|
@ -29,12 +30,12 @@ public final class BuildDynamicScene implements OutgoingPacket<DynamicSceneConte
|
|||
buffer.putS(player.getLocation().getZ());
|
||||
buffer.putLEShortA(player.getLocation().getSceneY());
|
||||
buffer.setBitAccess();
|
||||
RegionChunk[][][] chunks = new RegionChunk[13][13][4];
|
||||
RegionChunk[][][] chunks = new RegionChunk[MapChunkRenderer.BUILD_AREA_SIZE][MapChunkRenderer.BUILD_AREA_SIZE][Region.PLANES];
|
||||
int baseX = player.getLocation().getRegionX() - 6;
|
||||
int baseY = player.getLocation().getRegionY() - 6;
|
||||
for (int x = baseX; x <= player.getLocation().getRegionX() + 6; x++) {
|
||||
for (int y = baseY; y <= player.getLocation().getRegionY() + 6; y++) {
|
||||
for (int z = 0; z < 4; z++) {
|
||||
for (int z = 0; z < Region.PLANES; z++) {
|
||||
Region r = RegionManager.forId((x >> 3) << 8 | (y >> 3));
|
||||
if (r instanceof DynamicRegion) {
|
||||
chunks[x - baseX][y - baseY][z] = r.getChunks()[x - (r.getX() << 3)][y - (r.getY() << 3)][z];
|
||||
|
|
@ -42,9 +43,9 @@ public final class BuildDynamicScene implements OutgoingPacket<DynamicSceneConte
|
|||
}
|
||||
}
|
||||
}
|
||||
for (int plane = 0; plane < 4; plane++) {
|
||||
for (int offsetX = 0; offsetX < 13; offsetX++) {
|
||||
for (int offsetY = 0; offsetY < 13; offsetY++) {
|
||||
for (int plane = 0; plane < Region.PLANES; plane++) {
|
||||
for (int offsetX = 0; offsetX < MapChunkRenderer.BUILD_AREA_SIZE; offsetX++) {
|
||||
for (int offsetY = 0; offsetY < MapChunkRenderer.BUILD_AREA_SIZE; offsetY++) {
|
||||
RegionChunk c = chunks[offsetX][offsetY][plane];
|
||||
if (c == null || c.getBase().getX() < 0 || c.getBase().getY() < 0) {
|
||||
buffer.putBits(1, 0);
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import core.net.packet.context.ClearChunkContext;
|
|||
* @author Emperor
|
||||
*/
|
||||
public final class ClearRegionChunk implements OutgoingPacket<ClearChunkContext> {
|
||||
static final int buildAreaDepthInTiles = (2*MapChunkRenderer.buildAreaDepth+1) * 8;
|
||||
static final int buildAreaDepthInTiles = (2*MapChunkRenderer.BUILD_AREA_DEPTH +1) * 8;
|
||||
|
||||
@Override
|
||||
public void send(ClearChunkContext context) {
|
||||
|
|
|
|||
|
|
@ -242,4 +242,4 @@ class BlastFurnaceAreaTests {
|
|||
BlastFurnaceListeners().defineListeners()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue