From 6d7818951bea739d11f0cfa621891021122a8032 Mon Sep 17 00:00:00 2001 From: Player Name Date: Sat, 25 Jul 2026 16:49:51 +0200 Subject: [PATCH] tears of guthix and fix of resulting edge cases --- .../skill/construction/BuildingUtils.java | 20 ++-- .../global/skill/construction/Room.java | 31 +++--- .../minigame/vinesweeper/Vinesweeper.kt | 16 +-- .../tearsofguthix/TearsOfGuthixMinigame.kt | 53 ++++------ Server/src/main/core/api/ContentAPI.kt | 5 +- .../system/command/sets/SpawnCommandSet.kt | 4 +- .../src/main/core/game/world/map/Region.java | 2 +- .../main/core/game/world/map/RegionChunk.java | 100 ++++++++---------- .../main/core/game/world/map/RegionManager.kt | 5 +- .../game/world/map/build/LandscapeParser.java | 6 +- 10 files changed, 111 insertions(+), 131 deletions(-) diff --git a/Server/src/main/content/global/skill/construction/BuildingUtils.java b/Server/src/main/content/global/skill/construction/BuildingUtils.java index 158d7abbb..ad8b71bcd 100644 --- a/Server/src/main/content/global/skill/construction/BuildingUtils.java +++ b/Server/src/main/content/global/skill/construction/BuildingUtils.java @@ -289,9 +289,11 @@ public final class BuildingUtils { h.setDecorationIndex(decIndex); int objectId = hotspot.getHotspot().getObjectId(style); int index = chunk.getIndex(x, y, objectId, -1); - Scenery o = chunk.getObjects()[index][x][y]; - if (o != null && objectId == o.getId()) { - SceneryBuilder.replace(o, o.transform(hotspot.getHotspot().getDecorations()[decIndex].getObjectId(style))); + 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))); + } } } } @@ -308,9 +310,11 @@ public final class BuildingUtils { h.setDecorationIndex(decIndex); int objectId = bh.getObjectId(style); int index = chunk.getIndex(x, y, objectId, -1); - Scenery o = chunk.getObjects()[index][x][y]; - if (o != null && objectId == o.getId()) { - SceneryBuilder.replace(o, o.transform(bh.getDecorations()[decIndex].getObjectId(style))); + if (index != -1) { + Scenery o = chunk.getObjects()[x][y][index]; + if (objectId == o.getId()) { + SceneryBuilder.replace(o, o.transform(bh.getDecorations()[decIndex].getObjectId(style))); + } } } } @@ -423,7 +427,7 @@ public final class BuildingUtils { if (h != null) { int objectId = hotspot.getHotspot().getDecorations()[h.getDecorationIndex()].getObjectId(style); int index = chunk.getIndex(x, y, objectId, -1); - Scenery o = chunk.getObjects()[index][x][y]; + 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))); @@ -442,7 +446,7 @@ public final class BuildingUtils { if (h != null) { int objectId = bh.getDecorations()[h.getDecorationIndex()].getObjectId(style); int index = chunk.getIndex(x, y, objectId, -1); - Scenery o = chunk.getObjects()[index][x][y]; + Scenery o = chunk.getObjects()[x][y][index]; h.setDecorationIndex(-1); if (o != null && objectId == o.getId()) { SceneryBuilder.replace(o, o.transform(bh.getObjectId(style))); diff --git a/Server/src/main/content/global/skill/construction/Room.java b/Server/src/main/content/global/skill/construction/Room.java index 28f068ac4..508fa6370 100644 --- a/Server/src/main/content/global/skill/construction/Room.java +++ b/Server/src/main/content/global/skill/construction/Room.java @@ -131,21 +131,22 @@ public final class Room { int y = spot.getChunkY(); int id = spot.getHotspot().getObjectId(house.getStyle()); int index = chunk.getIndex(x, y, id, -1); - 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) { - id = spot.getHotspot().getDecorations()[spot.getDecorationIndex()].getObjectId(house.getStyle()); - if (spot.getHotspot().getType() == BuildHotspotType.CREST) { - id += house.getCrest().ordinal(); + 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))); - } 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())); + int[] pos = RegionChunk.getRotatedPosition(x, y, object.getSizeX(), object.getSizeY(), 0, rotation.toInteger()); + spot.setCurrentX(pos[0]); + spot.setCurrentY(pos[1]); } - 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) { @@ -167,7 +168,7 @@ public final class Room { for (int x = 0; x < 8; x++) { for (int y = 0; y < 8; y++) { for (int i = 0; i < RegionChunk.ARRAY_SIZE; i++) { - Scenery object = chunk.getObjects()[i][x][y]; + Scenery object = chunk.getObjects()[x][y][i]; if (object != null) { int id = object.getId(); boolean isBuilt = !object.getDefinition().hasAction("build"); @@ -197,7 +198,7 @@ public final class Room { 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.getObjects()[i][x][y]; + Scenery object = chunk.getObjects()[x][y][i]; if (object != null && BuildingUtils.isDoorHotspot(object)) { boolean edge = false; Room otherRoom = null; diff --git a/Server/src/main/content/minigame/vinesweeper/Vinesweeper.kt b/Server/src/main/content/minigame/vinesweeper/Vinesweeper.kt index 151a265da..0069671f4 100644 --- a/Server/src/main/content/minigame/vinesweeper/Vinesweeper.kt +++ b/Server/src/main/content/minigame/vinesweeper/Vinesweeper.kt @@ -374,10 +374,10 @@ class Vinesweeper : InteractionListener, InterfaceListener, MapArea { fun resetChunkIfBarren(chunk: RegionChunk) { val wipedHoles = ArrayList() - for (i in 0 until chunk.objects.size) { - for (x in 0 until 8) { - for (y in 0 until 8) { - val obj = chunk.objects[i][x][y] ?: continue + 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 } @@ -393,10 +393,10 @@ class Vinesweeper : InteractionListener, InterfaceListener, MapArea { } fun countFieldState(chunk: RegionChunk, emptyHoleList: ArrayList, seedHoleList: ArrayList) { - for (i in 0 until chunk.objects.size) { - for (x in 0 until 8) { - for (y in 0 until 8) { - val obj = chunk.objects[i][x][y] ?: continue + 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) { if (obj.location in SEED_LOCS) { seedHoleList.add(obj) diff --git a/Server/src/main/content/region/misthalin/lumbridge/quest/tearsofguthix/TearsOfGuthixMinigame.kt b/Server/src/main/content/region/misthalin/lumbridge/quest/tearsofguthix/TearsOfGuthixMinigame.kt index ab27cbd71..da71522ce 100644 --- a/Server/src/main/content/region/misthalin/lumbridge/quest/tearsofguthix/TearsOfGuthixMinigame.kt +++ b/Server/src/main/content/region/misthalin/lumbridge/quest/tearsofguthix/TearsOfGuthixMinigame.kt @@ -11,7 +11,9 @@ import core.game.node.entity.Entity import core.game.node.entity.player.Player import core.game.node.entity.skill.Skills import core.game.node.item.Item +import core.game.node.scenery.SceneryBuilder import core.game.world.map.Location +import core.game.world.map.RegionManager import core.game.world.map.zone.ZoneBorders import core.game.world.map.zone.ZoneRestriction import core.game.world.update.flag.context.Animation @@ -254,14 +256,12 @@ class TearsOfGuthixMinigame : InteractionListener, EventHook, MapArea } override fun defineListeners() { - on(Scenery.WEEPING_WALL_6660, SCENERY, "collect-from") { player, node -> animate(player, 2043) val index = TearsOfGuthixGlobalTick.allWalls.indexOf(node.location) setAttribute(player, attributeIsCollecting, index) return@on true } - } // Timer step per tick while you are in the minigame. @@ -330,7 +330,6 @@ class TearsOfGuthixMinigame : InteractionListener, EventHook, MapArea * Global Tick class to randomize the walls consistently for everyone. */ class TearsOfGuthixGlobalTick : TickListener { - companion object { var ticks = 0 var globalWallState = intArrayOf(0, 0, 2, 1, 2, 1, 0, 0, 2, 1) @@ -360,43 +359,29 @@ class TearsOfGuthixGlobalTick : TickListener { globalWallState = intArrayOf(0) + wallStates /* - * Explanation: The walls are layered sceneries, which makes it rabidly fucked to change them. - * What I did was to add the tears scenery first (essentially overriding the tears scenery), - * then add the WEEPING_WALL_6660 right after it so that the interactions are still there. - * this is how a layer is like: - * 1 - WEEPING_WALL_6660 - No model, but holds the option "collect-from" - * 2 - BLUE/GREEN/ABSENT - Model of the blue/green/absent waterfall. - * 3 - WEEPING_WALL_6664 - The actual model, but not interactive. - * 6661 - 6664 is left side, 6665 to 6668 is right side + * All walls have two objects: + * 1 - WEEPING_WALL_6660 (type 0) - No model, but holds the option "collect-from" + * 2 - BLUE/GREEN/ABSENT (type 4) - Model of the blue/green/absent waterfall. + * 6665, 6661, 6665 is blue on the north side + * 6662, 6666, 6662 is green on the south side */ wallStates.forEachIndexed { index, state -> - val scenery = getScenery(allWalls[index + 1])!! - val newSceneryId = if (state == 2) { - if (index + 1 <= 5) { - Scenery.GREEN_TEARS_6662 - } else { - Scenery.GREEN_TEARS_6666 + val wallLocation = allWalls[index + 1] + val currentWaterfall = RegionManager.getObject(wallLocation, 4)!! + val newWaterfallId = when (state) { + 2 -> { + if (index + 1 <= 5) Scenery.GREEN_TEARS_6662 else Scenery.GREEN_TEARS_6666 } - } else if (state == 1) { - if (index + 1 <= 5) { - Scenery.BLUE_TEARS_6661 - } else { - Scenery.BLUE_TEARS_6665 + 1 -> { + if (index + 1 <= 5) Scenery.BLUE_TEARS_6661 else Scenery.BLUE_TEARS_6665 } - } else { - if (index + 1 <= 5) { - Scenery.ABSENCE_OF_TEARS_6663 - } else { - Scenery.ABSENCE_OF_TEARS_6667 + else -> { + if (index + 1 <= 5) Scenery.ABSENCE_OF_TEARS_6663 else Scenery.ABSENCE_OF_TEARS_6667 } } - addScenery(core.game.node.scenery.Scenery( - newSceneryId, - scenery.location, - 4, - scenery.rotation - )) - addScenery(core.game.node.scenery.Scenery(Scenery.WEEPING_WALL_6660, scenery.location, 0, scenery.rotation)) + if (currentWaterfall.id != newWaterfallId) { + SceneryBuilder.replace(currentWaterfall, currentWaterfall.transform(newWaterfallId)) + } } } } \ No newline at end of file diff --git a/Server/src/main/core/api/ContentAPI.kt b/Server/src/main/core/api/ContentAPI.kt index 7e1d6f813..749324d36 100644 --- a/Server/src/main/core/api/ContentAPI.kt +++ b/Server/src/main/core/api/ContentAPI.kt @@ -1078,9 +1078,10 @@ fun findNPC(id: Int): NPC? { * @param x the X coordinate to use * @param y the Y coordinate to use * @param z the Z coordinate to use + * @param type the scenery type, -1 if any */ -fun getScenery(x: Int, y: Int, z: Int): Scenery? { - return RegionManager.getObject(z, x, y) +fun getScenery(x: Int, y: Int, z: Int, type: Int = -1): Scenery? { + return RegionManager.getObject(z, x, y, type) } /** diff --git a/Server/src/main/core/game/system/command/sets/SpawnCommandSet.kt b/Server/src/main/core/game/system/command/sets/SpawnCommandSet.kt index 0e2151425..f197553bb 100644 --- a/Server/src/main/core/game/system/command/sets/SpawnCommandSet.kt +++ b/Server/src/main/core/game/system/command/sets/SpawnCommandSet.kt @@ -185,8 +185,8 @@ class SpawnCommandSet : CommandSet(Privilege.ADMIN){ } } val stat = ArrayList(10) - for (i in 0 until chunk.statObjects.size) { - val obj = chunk.statObjects[i][player.location.chunkOffsetX][player.location.chunkOffsetY] + for (i in 0 until 4) { + val obj = chunk.statObjects[player.location.chunkOffsetX][player.location.chunkOffsetY][i] if (obj != null) { stat.add(obj) } diff --git a/Server/src/main/core/game/world/map/Region.java b/Server/src/main/core/game/world/map/Region.java index 40e455aea..6524772aa 100644 --- a/Server/src/main/core/game/world/map/Region.java +++ b/Server/src/main/core/game/world/map/Region.java @@ -558,7 +558,7 @@ public class Region { for (int offsetX = 0; offsetX < 8; offsetX++) { for (int offsetY = 0; offsetY < 8; offsetY++) { for (int i = 0; i < 4; i++) { - Scenery object = chunk.getObjects()[i][offsetX][offsetY]; + Scenery object = chunk.getObjects()[offsetX][offsetY][i]; if (object != null) { list.add(object); } diff --git a/Server/src/main/core/game/world/map/RegionChunk.java b/Server/src/main/core/game/world/map/RegionChunk.java index 3a5986abe..216d1556a 100644 --- a/Server/src/main/core/game/world/map/RegionChunk.java +++ b/Server/src/main/core/game/world/map/RegionChunk.java @@ -118,8 +118,8 @@ public class RegionChunk { this.base = base; this.currentBase = base; this.rotation = rotation; - this.statObjects = new Scenery[ARRAY_SIZE][SIZE][SIZE]; - this.objects = new Scenery[ARRAY_SIZE][SIZE][SIZE]; + this.statObjects = new Scenery[SIZE][SIZE][ARRAY_SIZE]; + this.objects = new Scenery[SIZE][SIZE][ARRAY_SIZE]; this.flags = new ChunkFlags(base.getX(), base.getY(), base.getZ()); this.projectileFlags = new ChunkFlags(base.getX(), base.getY(), base.getZ(), true); } @@ -136,10 +136,10 @@ public class RegionChunk { * Corrects objects' Locations when copying them from a template region into an instance - private version. */ private void rebaseObjects(Scenery[][][] objects) { - for (int i = 0; i < objects.length; i++) { + for (int i = 0; i < ARRAY_SIZE; i++) { for (int x = 0; x < SIZE; x++) { for (int y = 0; y < SIZE; y++) { - Scenery o = objects[i][x][y]; + Scenery o = objects[x][y][i]; if (o == null) { continue; } @@ -153,21 +153,21 @@ public class RegionChunk { * Makes a deep copy of an object list - private version. */ private void copyObjects(Scenery[][][] src, Scenery[][][] dest) { - for (int i = 0; i < src.length; i++) { - for (int x = 0; x < SIZE; x++) { - for (int y = 0; y < SIZE; y++) { - Scenery o = src[i][x][y]; + for (int x = 0; x < SIZE; x++) { + for (int y = 0; y < SIZE; y++) { + for (int i = 0; i < ARRAY_SIZE; i++) { + Scenery o = src[x][y][i]; if (o == null) { continue; } Scenery copy = o.transform(o.getId()); if (o instanceof Constructed) { - dest[i][x][y] = copy.asConstructed(); + dest[x][y][i] = copy.asConstructed(); } else { - dest[i][x][y] = copy; + dest[x][y][i] = copy; } - dest[i][x][y].setActive(o.isActive()); - dest[i][x][y].setRenderable(o.isRenderable()); + dest[x][y][i].setActive(o.isActive()); + dest[x][y][i].setRenderable(o.isRenderable()); } } } @@ -191,11 +191,11 @@ public class RegionChunk { * @return The slot it was added into. */ public int addStatDyn(Scenery object, int chunkOffsetX, int chunkOffsetY) { - for (int i = 0; i < statObjects.length; i++) { - Scenery current = statObjects[i][chunkOffsetX][chunkOffsetY]; + for (int i = 0; i < ARRAY_SIZE; i++) { + Scenery current = statObjects[chunkOffsetX][chunkOffsetY][i]; if (current == null) { - statObjects[i][chunkOffsetX][chunkOffsetY] = object; - objects[i][chunkOffsetX][chunkOffsetY] = object.transform(object.getId()); //deep copy so that active/renderable flags don't synchronize across multiple copies of e.g. a POH + 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; } if (current.getId() == object.getId()) { @@ -217,10 +217,10 @@ public class RegionChunk { public int add(Scenery object) { int chunkOffsetX = object.getLocation().getChunkOffsetX(); int chunkOffsetY = object.getLocation().getChunkOffsetY(); - for (int i = 0; i < objects.length; i++) { - Scenery current = objects[i][chunkOffsetX][chunkOffsetY]; + for (int i = 0; i < ARRAY_SIZE; i++) { + Scenery current = objects[chunkOffsetX][chunkOffsetY][i]; if (current == null) { - objects[i][chunkOffsetX][chunkOffsetY] = object.asConstructed(); + objects[chunkOffsetX][chunkOffsetY][i] = object.asConstructed(); object.setRenderable(true); object.setActive(true); return i; @@ -321,7 +321,7 @@ public class RegionChunk { for (int offsetX = 0; offsetX < 8; offsetX++) { for (int offsetY = 0; offsetY < 8; offsetY++) { for (int i = 0; i < ARRAY_SIZE; i++) { - Scenery object = objects[i][offsetX][offsetY]; + Scenery object = objects[offsetX][offsetY][i]; if (object != null) { list.add(object); } @@ -364,10 +364,10 @@ public class RegionChunk { items.clear(); items = null; } - for (int i = 0; i < objects.length; i++) { - for (int x = 0; x < objects[i].length; x++) { - for (int y = 0; y < objects[i][x].length; y++) { - statObjects[i][x][y] = objects[i][x][y] = null; + for (int x = 0; x < SIZE; x++) { + for (int y = 0; y < SIZE; y++) { + for (int i = 0; i < ARRAY_SIZE; i++) { + statObjects[x][y][i] = objects[x][y][i] = null; } } } @@ -392,11 +392,11 @@ public class RegionChunk { */ protected boolean appendUpdate(Player player, IoBuffer buffer) { boolean updated = false; - for (int i = 0; i < objects.length; i++) { - for (int x = 0; x < SIZE; x++) { - for (int y = 0; y < SIZE; y++) { - Scenery dyn = objects[i][x][y]; - Scenery stat = statObjects[i][x][y]; + for (int x = 0; x < SIZE; x++) { + for (int y = 0; y < SIZE; y++) { + for (int i = 0; i < ARRAY_SIZE; i++) { + Scenery dyn = objects[x][y][i]; + Scenery stat = statObjects[x][y][i]; if (dyn == stat) { continue; } @@ -522,11 +522,7 @@ public class RegionChunk { * @return The objects. */ public Scenery[] getObjects(int chunkOffsetX, int chunkOffsetY) { - Scenery[] result = new Scenery[ARRAY_SIZE]; - for (int i = 0; i < objects.length; i++) { - result[i] = objects[i][chunkOffsetX][chunkOffsetY]; - } - return result; + return objects[chunkOffsetX][chunkOffsetY]; } /** @@ -536,11 +532,7 @@ public class RegionChunk { * @return The objects. */ public Scenery[] getStatObjects(int chunkOffsetX, int chunkOffsetY) { - Scenery[] result = new Scenery[ARRAY_SIZE]; - for (int i = 0; i < statObjects.length; i++) { - result[i] = statObjects[i][chunkOffsetX][chunkOffsetY]; - } - return result; + return statObjects[chunkOffsetX][chunkOffsetY]; } /** @@ -567,18 +559,14 @@ public class RegionChunk { * @param type The scenery type. */ public int getIndex(int x, int y, int objectId, int type) { - for (int i = 0; i < objects.length; i++) { - Scenery o = objects[i][x][y]; + for (int i = 0; i < ARRAY_SIZE; i++) { + Scenery o = objects[x][y][i]; if (o != null) { if (objectId < 0) { if (type >= 0 && o.getType() != type) { continue; } - // Caller didn't ask for anything specific, so we assume they want whatever *interactable-excluding-examine* object is in here - // We should probably discourage this and instead make functions calling this function more specific - if (o.getDefinition().hasOptions(false)) { - return i; - } + 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 @@ -587,7 +575,7 @@ public class RegionChunk { } } } - return 0; + return -1; } /** @@ -672,8 +660,8 @@ public class RegionChunk { flags.getLandscape()[x][y] = from.getFlags().getLandscape()[x][y]; projectileFlags.getLandscape()[x][y] = from.getProjectileFlags().getLandscape()[x][y]; // Reflag any objects - for (int i = 0; i < objects.length; i++) { - Scenery obj = objects[i][x][y]; + for (int i = 0; i < ARRAY_SIZE; i++) { + Scenery obj = objects[x][y][i]; if (obj != null) { LandscapeParser.flagScenery(this, x, y, obj, false, true); } @@ -691,16 +679,14 @@ public class RegionChunk { log(this.getClass(), Log.ERR, "Region chunk was already rotated!"); return; } - Scenery[][][] copy = new Scenery[ARRAY_SIZE][SIZE][SIZE]; - int baseX = currentBase.getLocalX(); - int baseY = currentBase.getLocalY(); + Scenery[][][] copy = new Scenery[SIZE][SIZE][ARRAY_SIZE]; for (int x = 0; x < SIZE; x++) { for (int y = 0; y < SIZE; y++) { - for (int i = 0; i < objects.length; i++) { - Scenery object = copy[i][x][y] = objects[i][x][y]; + for (int i = 0; i < ARRAY_SIZE; i++) { + Scenery object = copy[x][y][i] = objects[x][y][i]; if (object != null) { SceneryBuilder.remove(object); - objects[i][x][y] = null; + objects[x][y][i] = null; } } } @@ -715,10 +701,10 @@ public class RegionChunk { 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 < objects.length; i++) { + for (int i = 0; i < ARRAY_SIZE; i++) { for (int x = 0; x < SIZE; x++) { for (int y = 0; y < SIZE; y++) { - Scenery object = copy[i][x][y]; + 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)); diff --git a/Server/src/main/core/game/world/map/RegionManager.kt b/Server/src/main/core/game/world/map/RegionManager.kt index b75b5b774..8a78e0a99 100644 --- a/Server/src/main/core/game/world/map/RegionManager.kt +++ b/Server/src/main/core/game/world/map/RegionManager.kt @@ -355,7 +355,10 @@ object RegionManager { Region.load(region) val chunk = region.chunks[loc.chunkX][loc.chunkY][loc.z] val index = chunk.getIndex(loc.chunkOffsetX, loc.chunkOffsetY, objectId, type) - val obj = chunk.objects[index][loc.chunkOffsetX][loc.chunkOffsetY] + if (index == -1) { + return null + } + val obj = chunk.objects[loc.chunkOffsetX][loc.chunkOffsetY][index] if (obj != null && !obj.isRenderable) { return null } diff --git a/Server/src/main/core/game/world/map/build/LandscapeParser.java b/Server/src/main/core/game/world/map/build/LandscapeParser.java index 3c6f44cec..618e3637a 100644 --- a/Server/src/main/core/game/world/map/build/LandscapeParser.java +++ b/Server/src/main/core/game/world/map/build/LandscapeParser.java @@ -158,13 +158,13 @@ public final class LandscapeParser { Region.load(region); RegionChunk chunk = region.getChunks()[loc.getChunkX()][loc.getChunkY()][loc.getZ()]; int index = chunk.getIndex(loc.getChunkOffsetX(), loc.getChunkOffsetY(), object.getId(), object.getType()); - Scenery current = chunk.getObjects()[index][loc.getChunkOffsetX()][loc.getChunkOffsetY()]; - if (current == null || current.getId() != object.getId()) { + if (index == -1) { return null; } + Scenery current = chunk.getObjects()[loc.getChunkOffsetX()][loc.getChunkOffsetY()][index]; current.setActive(false); object.setActive(false); - chunk.getObjects()[index][loc.getChunkOffsetX()][loc.getChunkOffsetY()] = null; + chunk.getObjects()[loc.getChunkOffsetX()][loc.getChunkOffsetY()][index] = null; SceneryDefinition def = object.getDefinition(); // Remove its clipping flags