diff --git a/Server/src/main/content/global/skill/construction/BuildingUtils.java b/Server/src/main/content/global/skill/construction/BuildingUtils.java index 27708ba49..6f4fe295e 100644 --- a/Server/src/main/content/global/skill/construction/BuildingUtils.java +++ b/Server/src/main/content/global/skill/construction/BuildingUtils.java @@ -201,7 +201,6 @@ public final class BuildingUtils { for (int i = 7; i >= 0; i--) { Item can = player.getInventory().getItem(new Item(WATERING_CAN - i, 1)); if (can != null && can.getSlot() > -1) { - System.out.println("Can index " + (i == 7 ? i + 2 : i + 1) + "."); player.getInventory().replace(new Item(WATERING_CAN - (i == 7 ? i + 2 : i + 1), 1), can.getSlot()); break; } diff --git a/Server/src/main/content/global/skill/construction/HouseManager.java b/Server/src/main/content/global/skill/construction/HouseManager.java index 081e3f0d0..3e2f05d88 100644 --- a/Server/src/main/content/global/skill/construction/HouseManager.java +++ b/Server/src/main/content/global/skill/construction/HouseManager.java @@ -396,10 +396,12 @@ public final class HouseManager { houseRegion = getPreparedRegion(); configureRoofs(); prepareHouseChunks(style, houseRegion, buildingMode, rooms); + houseRegion.flagActive(); if (hasDungeon()) { dungeonRegion = getPreparedRegion(); prepareDungeonChunks(style, dungeonRegion, houseRegion, buildingMode, rooms[3]); + dungeonRegion.flagActive(); } ZoneBuilder.configure(zone); @@ -411,6 +413,7 @@ public final class HouseManager { 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; } @@ -428,8 +431,7 @@ public final class HouseManager { @Override public BuildRegionChunk getChunk(int x, int y, int plane, @NotNull DynamicRegion dyn) { - BuildRegionChunk chunk = rooms[plane][x][y].getChunk().copy(dyn.getPlanes()[plane]); - return chunk; + return rooms[plane][x][y].getChunk().copy(dyn.getPlanes()[plane]); } @Override diff --git a/Server/src/main/core/Util.java b/Server/src/main/core/Util.java index 861df7c69..5bb17aaac 100644 --- a/Server/src/main/core/Util.java +++ b/Server/src/main/core/Util.java @@ -34,6 +34,9 @@ public class Util { public static double clamp(double input, double min, double max) { return Math.max(Math.min(input, max), min); } + public static int clamp(int input, int min, int max) { + return Math.max(Math.min(input, max), min); + } public static long nextMidnight(long currentTime) { Date date = new Date(); diff --git a/Server/src/main/core/game/world/map/BuildRegionChunk.java b/Server/src/main/core/game/world/map/BuildRegionChunk.java index 1c7bf97a3..b89a72a0c 100644 --- a/Server/src/main/core/game/world/map/BuildRegionChunk.java +++ b/Server/src/main/core/game/world/map/BuildRegionChunk.java @@ -13,6 +13,8 @@ import core.net.packet.out.ClearScenery; import core.net.packet.out.ConstructGroundItem; import core.net.packet.out.ConstructScenery; +import java.util.Arrays; + /** * A region chunk, used for easily modifying objects. * @author Emperor @@ -23,7 +25,7 @@ public class BuildRegionChunk extends RegionChunk { /** * The maximum amount of objects to be stored on one tile in the chunk. */ - public static final int ARRAY_SIZE = 5; + public static final int ARRAY_SIZE = 10; /** * The list of changes made. @@ -39,13 +41,17 @@ public class BuildRegionChunk extends RegionChunk { public BuildRegionChunk(Location base, int rotation, RegionPlane plane) { super(base, rotation, plane); this.objects = new Scenery[ARRAY_SIZE][8][8]; - for (int x = 0; x < SIZE; x++) { - for (int y = 0; y < SIZE; y++) { - if(super.objects[x][y] != null) { - this.objects[0][x][y] = new Scenery(super.objects[x][y]); - } - } - } + } + + public BuildRegionChunk(Location base, int rotation, RegionPlane plane, Scenery[][] objects) { + this(base, rotation, plane); + for (int x = 0; x < SIZE; x++) { + for (int y = 0; y < SIZE; y++) { + if(objects[x][y] != null) { + this.objects[0][x][y] = new Scenery(objects[x][y]); + } + } + } } @Override @@ -141,6 +147,22 @@ public class BuildRegionChunk extends RegionChunk { return chunk; } + @Override public void rebuildFlags(RegionPlane from) { + for (int x = 0; x < 8; x++) { + for (int y = 0; y < 8; y++) { + Location loc = currentBase.transform(x,y,0); + Location fromLoc = base.transform(x,y,0); + plane.getFlags().getLandscape()[loc.getLocalX()][loc.getLocalY()] = from.getFlags().getLandscape()[fromLoc.getLocalX()][fromLoc.getLocalY()]; + plane.getFlags().clearFlag(x, y); + for (int i = 0; i < ARRAY_SIZE; i++) { + Scenery obj = objects[i][x][y]; + if (obj != null) + LandscapeParser.applyClippingFlagsFor(plane, loc.getLocalX(), loc.getLocalY(), obj); + } + } + } + } + @Override public void clear() { super.clear(); @@ -284,4 +306,19 @@ public class BuildRegionChunk extends RegionChunk { public Scenery[][] getObjects(int index) { return objects[index]; } + + @Override + public void setCurrentBase(Location currentBase) { + 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++) { + if (objects[i][x][y] != null) { + Location newLoc = currentBase.transform(x, y, 0); + objects[i][x][y].setLocation(newLoc); + } + } + } + } + super.setCurrentBase(currentBase); + } } diff --git a/Server/src/main/core/game/world/map/RegionChunk.java b/Server/src/main/core/game/world/map/RegionChunk.java index 816ac5b0c..999d1644a 100644 --- a/Server/src/main/core/game/world/map/RegionChunk.java +++ b/Server/src/main/core/game/world/map/RegionChunk.java @@ -83,7 +83,7 @@ public class RegionChunk { * @return The region chunk. */ public BuildRegionChunk copy(RegionPlane plane) { - return new BuildRegionChunk(base, rotation, plane); + return new BuildRegionChunk(base, rotation, plane, this.objects); } /** @@ -365,4 +365,18 @@ public class RegionChunk { this.currentBase = currentBase; } + public void rebuildFlags(RegionPlane from) { + for (int x = 0; x < 8; x++) { + for (int y = 0; y < 8; y++) { + Location loc = currentBase.transform(x,y,0); + Location fromLoc = base.transform(x,y,0); + plane.getFlags().getLandscape()[loc.getLocalX()][loc.getLocalY()] = from.getFlags().getLandscape()[fromLoc.getLocalX()][fromLoc.getLocalY()]; + plane.getFlags().clearFlag(x, y); + Scenery obj = objects[x][y]; + if (obj != null) + LandscapeParser.flagScenery(plane, loc.getLocalX(), loc.getLocalY(), obj, false, true); + } + } + } + } \ No newline at end of file diff --git a/Server/src/main/core/game/world/map/RegionPlane.java b/Server/src/main/core/game/world/map/RegionPlane.java index 15b68bc03..2a3f2ab0d 100644 --- a/Server/src/main/core/game/world/map/RegionPlane.java +++ b/Server/src/main/core/game/world/map/RegionPlane.java @@ -139,6 +139,10 @@ public final class RegionPlane { } return chunks[chunkX][chunkY] = new RegionChunk(region.getBaseLocation().transform(chunkX << 3, chunkY << 3, plane), 0, this); } + + public void setRegionChunk(int chunkX, int chunkY, RegionChunk chunk) { + chunks[chunkX][chunkY] = chunk; + } /** * Removes a scenery. diff --git a/Server/src/main/core/game/world/map/build/DynamicRegion.java b/Server/src/main/core/game/world/map/build/DynamicRegion.java index 56451386c..02f61db29 100644 --- a/Server/src/main/core/game/world/map/build/DynamicRegion.java +++ b/Server/src/main/core/game/world/map/build/DynamicRegion.java @@ -215,14 +215,18 @@ public final class DynamicRegion extends Region { int regionX = ((regionId >> 8) & 0xFF) << 6; int regionY = (regionId & 0xFF) << 6; DynamicRegion region = new DynamicRegion(regionId, to.getRegionX() >> 3, to.getRegionY() >> 3); + Region base = RegionManager.forId(regionId); + Region.load(base); for (int offsetX = 0; offsetX < 8; offsetX++) { for (int offsetY = 0; offsetY < 8; offsetY++) { int x = regionX + (offsetX << 3); int y = regionY + (offsetY << 3); for (int plane = 0; plane < 4; plane++) { - RegionChunk c = region.chunks[plane][offsetX][offsetY]; + RegionChunk c = base.getPlanes()[plane].getRegionChunk(offsetX, offsetY); if (c == null) { region.chunks[plane][offsetX][offsetY] = c = new RegionChunk(Location.create(0, 0, 0), 0, region.getPlanes()[plane]); + } else { + region.replaceChunk(plane, offsetX, offsetY, (c = c.copy(region.getPlanes()[plane])), base); } c.setRotation(0); c.setBase(Location.create(x, y, plane)); @@ -330,41 +334,11 @@ public final class DynamicRegion extends Region { } } } else { - chunk.clear(); Region.load(fromRegion); Location l = chunk.getBase(); - chunk.setCurrentBase(getBaseLocation().transform(x << 3, y << 3, 0)); - Location regionBase = fromRegion.getBaseLocation(); RegionPlane rp = fromRegion.getPlanes()[l.getZ()]; - for (int i = 0; i < 8; i++) { - for (int j = 0; j < 8; j++) { - int toX = (x << 3) + i; - int toY = (y << 3) + j; - int fromX = (l.getX() - regionBase.getX()) + i; - int fromY = (l.getY() - regionBase.getY()) + j; - p.getFlags().getLandscape()[toX][toY] = rp.getFlags().getLandscape()[fromX][fromY]; - p.getFlags().flag(fromX, fromY, rp.getFlags().getFlag(fromX, fromY)); - p.getProjectileFlags().flag(fromX, fromY, rp.getFlags().getFlag(fromX, fromY)); - Scenery[] objects = { rp.getChunkObject(fromX, fromY) }; - RegionChunk ch = rp.getChunks()[fromX >> 3][fromY >> 3]; - if (ch instanceof BuildRegionChunk) { - BuildRegionChunk bc = (BuildRegionChunk) ch; - objects = new Scenery[BuildRegionChunk.ARRAY_SIZE]; - for (int k = 0; k < objects.length; k++) { - objects[k] = bc.get(i, j, k); - } - } - for (Scenery object : objects) { - if (object != null) { - object = object.transform(object.getId(), object.getRotation(), getBaseLocation().transform(toX, toY, 0)); - LandscapeParser.flagScenery(p, toX, toY, object, false, true);//chunk instanceof BuildRegionChunk);//.addGameObject(object, true); - } else { - p.add(null, toX, toY, true); - } - } - } - } - + chunk.setCurrentBase(getBaseLocation().transform(x << 3, y << 3, z)); + chunk.rebuildFlags(rp); } } 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 b3df2188a..577ad4bfa 100644 --- a/Server/src/main/core/game/world/map/build/LandscapeParser.java +++ b/Server/src/main/core/game/world/map/build/LandscapeParser.java @@ -88,6 +88,22 @@ public final class LandscapeParser { */ public static void flagScenery(RegionPlane plane, int localX, int localY, Scenery object, boolean landscape, boolean storeObjects) { Region.load(plane.getRegion()); + SceneryDefinition def = object.getDefinition(); + object.setActive(true); + boolean add = storeObjects || !landscape || def.getChildObject(null).hasActions(); + if (add) { + addPlaneObject(plane, object, localX, localY, landscape, storeObjects); + } + + if (!applyClippingFlagsFor(plane, localX, localY, object)) + return; + + if (!storeObjects && !add && (!def.getChildObject(null).getName().equals("null"))) { + addPlaneObject(plane, object, localX, localY, landscape, false); + } + } + + public static boolean applyClippingFlagsFor(RegionPlane plane, int localX, int localY, Scenery object) { SceneryDefinition def = object.getDefinition(); int sizeX; int sizeY; @@ -98,15 +114,6 @@ public final class LandscapeParser { sizeX = def.sizeY; sizeY = def.sizeX; } - - object.setActive(true); - boolean add = storeObjects || !landscape || def.getChildObject(null).hasActions(); - if (add) { - addPlaneObject(plane, object, localX, localY, landscape, storeObjects); - } - // if (localX == 34 && localY == 32 && plane.getRegion().getId() == 14746) { - // System.out.println(object + ", " + Arrays.toString(object.getDefinition().getOptions()) + ", " + object.getDefinition().projectileClipped); - // } int type = object.getType(); if (type == 22) { //Tile plane.getFlags().getLandscape()[localX][localY] = true; @@ -133,11 +140,9 @@ public final class LandscapeParser { } } } else { - return; - } - if (!storeObjects && !add && (!def.getChildObject(null).getName().equals("null"))) { - addPlaneObject(plane, object, localX, localY, landscape, false); + return false; } + return true; } /** diff --git a/Server/src/main/core/net/packet/in/Decoders530.kt b/Server/src/main/core/net/packet/in/Decoders530.kt index 327ca29d9..1f7d63f74 100644 --- a/Server/src/main/core/net/packet/in/Decoders530.kt +++ b/Server/src/main/core/net/packet/in/Decoders530.kt @@ -1,5 +1,6 @@ package core.net.packet.`in` +import core.Util.clamp import core.game.node.entity.player.Player import core.net.packet.IoBuffer import core.tools.StringUtils @@ -650,9 +651,11 @@ enum class Decoders530(val opcode: Int) { }, CHAT_MESSAGE(237) { override fun decode(player: Player, buffer: IoBuffer): Packet { - val effects = buffer.short + val effectPrefix = clamp(buffer.get(), 0, 11) + val effectSuffix = clamp(buffer.get(), 0, 5) val numChars = buffer.smart val message = StringUtils.decryptPlayerChat(buffer, numChars) + val effects = (effectPrefix shl 8) or effectSuffix return Packet.ChatMessage(player, effects, message) } },