mirror of
https://gitlab.com/2009scape/2009scape.git
synced 2025-12-10 10:20:41 -07:00
Fixed construction door and wall placement
Fixed the bug where some hotspots were still visible even in non-building mode
This commit is contained in:
parent
81495ab8a8
commit
21a07841f6
3 changed files with 104 additions and 80 deletions
|
|
@ -1,9 +1,4 @@
|
||||||
package content.global.skill.construction;
|
package content.global.skill.construction;
|
||||||
|
|
||||||
|
|
||||||
//import org.arios.game.content.global.DeadmanTimedAction;
|
|
||||||
//import org.arios.game.node.entity.player.info.login.SavingModule;
|
|
||||||
|
|
||||||
import core.api.regionspec.RegionSpecification;
|
import core.api.regionspec.RegionSpecification;
|
||||||
import core.api.regionspec.contracts.FillChunkContract;
|
import core.api.regionspec.contracts.FillChunkContract;
|
||||||
import core.game.dialogue.FacialExpression;
|
import core.game.dialogue.FacialExpression;
|
||||||
|
|
@ -17,12 +12,10 @@ import core.game.world.map.zone.ZoneBorders;
|
||||||
import core.game.world.map.zone.ZoneBuilder;
|
import core.game.world.map.zone.ZoneBuilder;
|
||||||
import core.game.world.update.flag.context.Animation;
|
import core.game.world.update.flag.context.Animation;
|
||||||
import core.tools.Log;
|
import core.tools.Log;
|
||||||
import kotlin.Unit;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.json.simple.JSONArray;
|
import org.json.simple.JSONArray;
|
||||||
import org.json.simple.JSONObject;
|
import org.json.simple.JSONObject;
|
||||||
import core.tools.SystemLogger;
|
|
||||||
import core.game.world.GameWorld;
|
import core.game.world.GameWorld;
|
||||||
import org.rs09.consts.Sounds;
|
import org.rs09.consts.Sounds;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,13 @@ package content.global.skill.construction;
|
||||||
|
|
||||||
|
|
||||||
import core.game.node.entity.player.Player;
|
import core.game.node.entity.player.Player;
|
||||||
|
import core.game.node.scenery.Constructed;
|
||||||
import core.game.node.scenery.Scenery;
|
import core.game.node.scenery.Scenery;
|
||||||
import core.game.node.scenery.SceneryBuilder;
|
import core.game.node.scenery.SceneryBuilder;
|
||||||
import core.game.world.map.*;
|
import core.game.world.map.*;
|
||||||
|
import core.tools.Log;
|
||||||
|
|
||||||
|
import static core.api.ContentAPIKt.log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a room.
|
* Represents a room.
|
||||||
|
|
@ -93,7 +97,7 @@ public final class Room {
|
||||||
Region.load(region, true);
|
Region.load(region, true);
|
||||||
chunk = region.getPlanes()[style.getPlane()].getRegionChunk(properties.getChunkX(), properties.getChunkY());
|
chunk = region.getPlanes()[style.getPlane()].getRegionChunk(properties.getChunkX(), properties.getChunkY());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the hotspot object for the given hotspot type.
|
* Gets the hotspot object for the given hotspot type.
|
||||||
* @param hotspot The hotspot type.
|
* @param hotspot The hotspot type.
|
||||||
|
|
@ -154,6 +158,7 @@ public final class Room {
|
||||||
chunk.rotate(rotation);
|
chunk.rotate(rotation);
|
||||||
}
|
}
|
||||||
if (!house.isBuildingMode()) {
|
if (!house.isBuildingMode()) {
|
||||||
|
placeDoors(housePlane, house, chunk);
|
||||||
removeHotspots(housePlane, house, chunk);
|
removeHotspots(housePlane, house, chunk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -165,17 +170,16 @@ public final class Room {
|
||||||
* @param chunk The region chunk used.
|
* @param chunk The region chunk used.
|
||||||
*/
|
*/
|
||||||
private void removeHotspots(int housePlane, HouseManager house, BuildRegionChunk chunk) {
|
private void removeHotspots(int housePlane, HouseManager house, BuildRegionChunk chunk) {
|
||||||
for (int i = 0; i < BuildRegionChunk.ARRAY_SIZE; i++) {
|
if (properties.isRoof()) return;
|
||||||
for (int x = 0; x < 8; x++) {
|
for (int x = 0; x < 8; x++) {
|
||||||
for (int y = 0; y < 8; y++) {
|
for (int y = 0; y < 8; y++) {
|
||||||
|
for (int i = 0; i < BuildRegionChunk.ARRAY_SIZE; i++) {
|
||||||
Scenery object = chunk.get(x, y, i);
|
Scenery object = chunk.get(x, y, i);
|
||||||
if (object != null && object.getDefinition().hasAction("Build")) {
|
if (object != null) {
|
||||||
if (properties.isChamber() && BuildingUtils.isDoorHotspot(object)) {
|
boolean isBuilt = object instanceof Constructed;
|
||||||
if (!placeDoors(house, chunk, object, housePlane, x, y, rotation)) {
|
boolean isWall = object.getId() == 13065 || object.getId() == house.getStyle().getWallId();
|
||||||
SceneryBuilder.remove(object);
|
boolean isDoor = object.getId() == house.getStyle().getDoorId() || object.getId() == house.getStyle().getSecondDoorId();
|
||||||
chunk.remove(object);
|
if (!isBuilt && !isWall && !isDoor) {
|
||||||
}
|
|
||||||
} else {
|
|
||||||
SceneryBuilder.remove(object);
|
SceneryBuilder.remove(object);
|
||||||
chunk.remove(object);
|
chunk.remove(object);
|
||||||
}
|
}
|
||||||
|
|
@ -186,65 +190,92 @@ public final class Room {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Places the doors when needed.
|
* Replaces the door hotspots with doors, walls, or passageways as needed.
|
||||||
* @param chunk The chunk.
|
* TODO: it is believed that doors authentically remember their open/closed state for the usual duration (see e.g. https://www.youtube.com/watch?v=nRGux739h8s 1:00 vs 1:55), but this is not possible with the current HouseManager approach, which deallocates the instance as soon as the player leaves.
|
||||||
* @param object The object.
|
* @param housePlane The room's plane in house.
|
||||||
* @param x The x-coordinate of the object.
|
* @param house The house manager.
|
||||||
* @param y The y-coordinate of the object.
|
* @param chunk The region chunk used.
|
||||||
*/
|
*/
|
||||||
private boolean placeDoors(HouseManager house, BuildRegionChunk chunk, Scenery object, int z, int x, int y, Direction rotation) {
|
private void placeDoors(int housePlane, HouseManager house, BuildRegionChunk chunk) {
|
||||||
int doorX;
|
Room[][][] rooms = house.getRooms();
|
||||||
int doorY;
|
int rx = chunk.getCurrentBase().getChunkX();
|
||||||
switch (rotation) {
|
int ry = chunk.getCurrentBase().getChunkY();
|
||||||
case EAST:
|
for (int i = 0; i < BuildRegionChunk.ARRAY_SIZE; i++) {
|
||||||
doorX = y;
|
for (int x = 0; x < 8; x++) {
|
||||||
doorY = 7 - x;
|
for (int y = 0; y < 8; y++) {
|
||||||
break;
|
Scenery object = chunk.get(x, y, i);
|
||||||
case SOUTH:
|
if (object != null && BuildingUtils.isDoorHotspot(object)) {
|
||||||
doorX = 7 - x;
|
boolean edge = false;
|
||||||
doorY = 7 - y;
|
Room otherRoom = null;
|
||||||
break;
|
switch (object.getRotation()) {
|
||||||
case WEST:
|
case 0: //east
|
||||||
doorX = 7 - y;
|
edge = rx == 0;
|
||||||
doorY = x;
|
otherRoom = edge ? null : rooms[housePlane][rx - 1][ry];
|
||||||
break;
|
break;
|
||||||
default:
|
case 1: //south
|
||||||
doorX = x;
|
edge = ry == 7;
|
||||||
doorY = y;
|
otherRoom = edge ? null : rooms[housePlane][rx][ry + 1];
|
||||||
break;
|
break;
|
||||||
}
|
case 2: //west
|
||||||
int chunkX = chunk.getCurrentBase().getChunkX();
|
edge = rx == 7;
|
||||||
int chunkY = chunk.getCurrentBase().getChunkY();
|
otherRoom = edge ? null : rooms[housePlane][rx + 1][ry];
|
||||||
boolean houseExit = true;
|
break;
|
||||||
Room r;
|
case 3: //north
|
||||||
if (doorX == 0 && chunkX > 0 && (r = house.getRooms()[z][chunkX - 1][chunkY]) != null && r.getProperties().isChamber()) {
|
edge = ry == 0;
|
||||||
houseExit = false;
|
otherRoom = edge ? null : rooms[housePlane][rx][ry - 1];
|
||||||
}
|
break;
|
||||||
else if (doorX == 7 && chunkX < 7 && (r = house.getRooms()[z][chunkX + 1][chunkY]) != null && r.getProperties().isChamber()) {
|
default:
|
||||||
houseExit = false;
|
log(this.getClass(), Log.ERR, "Impossible rotation when placing doors??");
|
||||||
}
|
}
|
||||||
else if (doorY == 0 && chunkY > 0 && (r = house.getRooms()[z][chunkX][chunkY - 1]) != null && r.getProperties().isChamber()) {
|
int replaceId = getReplaceId(housePlane, house, this, edge, otherRoom, object);
|
||||||
houseExit = false;
|
if (replaceId == -1) {
|
||||||
}
|
continue;
|
||||||
else if (doorY == 7 && chunkY < 7 && (r = house.getRooms()[z][chunkX][chunkY + 1]) != null && r.getProperties().isChamber()) {
|
}
|
||||||
houseExit = false;
|
SceneryBuilder.replace(object, object.transform(replaceId));
|
||||||
}
|
}
|
||||||
int replaceId = object.getId() % 2 != 0 ? house.getStyle().getDoorId() : house.getStyle().getSecondDoorId();
|
}
|
||||||
houseExit = false;
|
|
||||||
if (z != 0 && houseExit) {
|
|
||||||
r = house.getRooms()[z][chunkX][chunkY];
|
|
||||||
if (r.getProperties().isDungeon()) {
|
|
||||||
replaceId = 13065;
|
|
||||||
} else {
|
|
||||||
replaceId = house.getStyle().getWallId();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!houseExit) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return SceneryBuilder.replace(object, object.transform(replaceId, object.getRotation(), chunk.getCurrentBase().transform(x, y, 0)), true, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if rooms transition between inside<>outside the house and returns the appropriate door replacement.
|
||||||
|
* @param housePlane The room's plane in house.
|
||||||
|
* @param house The house manager.
|
||||||
|
* @param room The room the door is in.
|
||||||
|
* @param edge Whether the door is adjacent to an edge.
|
||||||
|
* @param otherRoom The room the door is adjacent to.
|
||||||
|
* @param object The door object itself.
|
||||||
|
*/
|
||||||
|
private int getReplaceId(int housePlane, HouseManager house, Room room, boolean edge, Room otherRoom, Scenery object) {
|
||||||
|
boolean thisOutside = !room.getProperties().isChamber();
|
||||||
|
if (edge && thisOutside) {
|
||||||
|
// No door or wall
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!edge) {
|
||||||
|
boolean otherOutside = otherRoom == null || !otherRoom.getProperties().isChamber();
|
||||||
|
if (thisOutside == otherOutside) {
|
||||||
|
// Free passage, unless the other room has a blind wall here
|
||||||
|
if (otherRoom == null) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
boolean exit = otherRoom.getExits()[object.getRotation()];
|
||||||
|
if (exit) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (thisOutside != otherOutside && housePlane == 0) {
|
||||||
|
// Door if we are the inside room only
|
||||||
|
if (thisOutside) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return object.getId() % 2 != 0 ? house.getStyle().getDoorId() : house.getStyle().getSecondDoorId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return room.getProperties().isDungeon() ? 13065 : house.getStyle().getWallId();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the decoration index for a group of object ids
|
* Sets the decoration index for a group of object ids
|
||||||
* @param index The index.
|
* @param index The index.
|
||||||
|
|
@ -392,4 +423,4 @@ public final class Room {
|
||||||
return rotation;
|
return rotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
package content.global.skill.construction.decoration
|
package content.global.skill.construction.decoration
|
||||||
|
|
||||||
|
import content.global.skill.construction.BuildHotspot
|
||||||
|
import content.global.skill.construction.HousingStyle
|
||||||
import core.cache.def.impl.SceneryDefinition
|
import core.cache.def.impl.SceneryDefinition
|
||||||
import core.game.global.action.DoorActionHandler
|
import core.game.global.action.DoorActionHandler
|
||||||
import core.game.interaction.OptionHandler
|
import core.game.interaction.OptionHandler
|
||||||
import core.game.node.Node
|
import core.game.node.Node
|
||||||
import core.game.node.scenery.Scenery
|
|
||||||
import core.game.node.entity.player.Player
|
import core.game.node.entity.player.Player
|
||||||
import content.global.skill.construction.BuildHotspot
|
import core.game.node.scenery.Scenery
|
||||||
import content.global.skill.construction.HousingStyle
|
|
||||||
import core.plugin.Initializable
|
import core.plugin.Initializable
|
||||||
import core.plugin.Plugin
|
import core.plugin.Plugin
|
||||||
|
|
||||||
|
|
@ -38,11 +38,11 @@ class ConstructionDoorPlugin : OptionHandler() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handle(player: Player, node: Node, option: String): Boolean {
|
override fun handle(player: Player, node: Node, option: String): Boolean {
|
||||||
val `object` = node as Scenery
|
|
||||||
val second = DoorActionHandler.getSecondDoor(`object`, player)
|
|
||||||
when (option) {
|
when (option) {
|
||||||
"pick-lock", "force" -> return false //TODO
|
"pick-lock", "force" -> return false //TODO
|
||||||
}
|
}
|
||||||
|
val `object` = node as Scenery
|
||||||
|
val second = DoorActionHandler.getSecondDoor(`object`, player)
|
||||||
DoorActionHandler.open(`object`, second, getReplaceId(`object`), getReplaceId(second), true, 500, false)
|
DoorActionHandler.open(`object`, second, getReplaceId(`object`), getReplaceId(second), true, 500, false)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
@ -80,4 +80,4 @@ class ConstructionDoorPlugin : OptionHandler() {
|
||||||
intArrayOf(13119, 13121)
|
intArrayOf(13119, 13121)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue