You've already forked Arcturus-Morningstar-Extended
mirror of
https://github.com/duckietm/Arcturus-Morningstar-Extended.git
synced 2026-06-19 15:06:19 +00:00
Merge pull request #12 from simoleo89/pr/underpass-room-setting
feat(pathfinder): underpass walk-under-furniture with per-room setting
This commit is contained in:
@@ -0,0 +1 @@
|
||||
ALTER TABLE `rooms` ADD COLUMN `allow_underpass` ENUM('0','1') NOT NULL DEFAULT '0' AFTER `move_diagonally`;
|
||||
@@ -156,6 +156,7 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
|
||||
private volatile boolean promoted;
|
||||
private volatile int tradeMode;
|
||||
private volatile boolean moveDiagonally;
|
||||
private volatile boolean allowUnderpass;
|
||||
private volatile boolean jukeboxActive;
|
||||
private volatile boolean hideWired;
|
||||
private RoomPromotion promotion;
|
||||
@@ -239,6 +240,7 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
|
||||
|
||||
this.tradeMode = set.getInt("trade_mode");
|
||||
this.moveDiagonally = set.getString("move_diagonally").equals("1");
|
||||
this.allowUnderpass = set.getString("allow_underpass").equals("1");
|
||||
|
||||
this.preLoaded = true;
|
||||
this.allowBotsWalk = true;
|
||||
@@ -1077,7 +1079,7 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
|
||||
if (this.needsUpdate) {
|
||||
try (Connection connection = Emulator.getDatabase().getDataSource()
|
||||
.getConnection(); PreparedStatement statement = connection.prepareStatement(
|
||||
"UPDATE rooms SET name = ?, description = ?, password = ?, state = ?, users_max = ?, category = ?, score = ?, paper_floor = ?, paper_wall = ?, paper_landscape = ?, thickness_wall = ?, wall_height = ?, thickness_floor = ?, moodlight_data = ?, tags = ?, allow_other_pets = ?, allow_other_pets_eat = ?, allow_walkthrough = ?, allow_hidewall = ?, chat_mode = ?, chat_weight = ?, chat_speed = ?, chat_hearing_distance = ?, chat_protection =?, who_can_mute = ?, who_can_kick = ?, who_can_ban = ?, poll_id = ?, guild_id = ?, roller_speed = ?, override_model = ?, is_staff_picked = ?, promoted = ?, trade_mode = ?, move_diagonally = ?, owner_id = ?, owner_name = ?, jukebox_active = ?, hidewired = ? WHERE id = ?")) {
|
||||
"UPDATE rooms SET name = ?, description = ?, password = ?, state = ?, users_max = ?, category = ?, score = ?, paper_floor = ?, paper_wall = ?, paper_landscape = ?, thickness_wall = ?, wall_height = ?, thickness_floor = ?, moodlight_data = ?, tags = ?, allow_other_pets = ?, allow_other_pets_eat = ?, allow_walkthrough = ?, allow_hidewall = ?, chat_mode = ?, chat_weight = ?, chat_speed = ?, chat_hearing_distance = ?, chat_protection =?, who_can_mute = ?, who_can_kick = ?, who_can_ban = ?, poll_id = ?, guild_id = ?, roller_speed = ?, override_model = ?, is_staff_picked = ?, promoted = ?, trade_mode = ?, move_diagonally = ?, owner_id = ?, owner_name = ?, jukebox_active = ?, hidewired = ?, allow_underpass = ? WHERE id = ?")) {
|
||||
statement.setString(1, this.name);
|
||||
statement.setString(2, this.description);
|
||||
statement.setString(3, this.password);
|
||||
@@ -1126,7 +1128,8 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
|
||||
statement.setString(37, this.ownerName);
|
||||
statement.setString(38, this.jukeboxActive ? "1" : "0");
|
||||
statement.setString(39, this.hideWired ? "1" : "0");
|
||||
statement.setInt(40, this.id);
|
||||
statement.setString(40, this.allowUnderpass ? "1" : "0");
|
||||
statement.setInt(41, this.id);
|
||||
statement.executeUpdate();
|
||||
this.needsUpdate = false;
|
||||
} catch (SQLException e) {
|
||||
@@ -1408,6 +1411,14 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
|
||||
this.allowWalkthrough = allowWalkthrough;
|
||||
}
|
||||
|
||||
public boolean isAllowUnderpass() {
|
||||
return this.allowUnderpass;
|
||||
}
|
||||
|
||||
public void setAllowUnderpass(boolean allowUnderpass) {
|
||||
this.allowUnderpass = allowUnderpass;
|
||||
}
|
||||
|
||||
public boolean isAllowBotsWalk() {
|
||||
return this.allowBotsWalk;
|
||||
}
|
||||
|
||||
@@ -448,6 +448,48 @@ public class RoomItemManager {
|
||||
return highestItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the top walkable item at a position, considering underpass.
|
||||
* If the topmost item is elevated enough to walk under, returns the highest item at walk surface level instead.
|
||||
*/
|
||||
public HabboItem getWalkableItemAt(int x, int y) {
|
||||
HabboItem topItem = this.getTopItemAt(x, y);
|
||||
if (topItem == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// If underpass is disabled for this room, just return the top item
|
||||
if (!this.room.isAllowUnderpass()) {
|
||||
return topItem;
|
||||
}
|
||||
|
||||
// If the top item is walkable, just return it
|
||||
if (topItem.isWalkable() || topItem.getBaseItem().allowWalk() || topItem.getBaseItem().allowSit() || topItem.getBaseItem().allowLay()) {
|
||||
return topItem;
|
||||
}
|
||||
|
||||
// Check for underpass: get the walk surface height
|
||||
double walkSurface = this.room.getLayout() != null ? this.room.getLayout().getHeightAtSquare(x, y) : 0;
|
||||
HabboItem walkSurfaceItem = null;
|
||||
|
||||
for (HabboItem item : this.getItemsAt(x, y)) {
|
||||
if (item.isWalkable() || item.getBaseItem().allowWalk() || item.getBaseItem().allowSit() || item.getBaseItem().allowLay()) {
|
||||
double itemTop = item.getZ() + Item.getCurrentHeight(item);
|
||||
if (itemTop > walkSurface) {
|
||||
walkSurface = itemTop;
|
||||
walkSurfaceItem = item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If there's enough clearance under the top blocking item, return the walk surface item
|
||||
if (topItem.getZ() - walkSurface >= RoomLayout.UNDERPASS_HEIGHT) {
|
||||
return walkSurfaceItem;
|
||||
}
|
||||
|
||||
return topItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the top item from a set of tiles.
|
||||
*/
|
||||
|
||||
@@ -19,6 +19,7 @@ public class RoomLayout {
|
||||
protected static final int DIAGONALMOVEMENTCOST = 14;
|
||||
public static double MAXIMUM_STEP_HEIGHT = 1.5;
|
||||
public static boolean ALLOW_FALLING = true;
|
||||
public static double UNDERPASS_HEIGHT = 1.5;
|
||||
public boolean CANMOVEDIAGONALY = true;
|
||||
private String name;
|
||||
private short doorX;
|
||||
|
||||
@@ -91,9 +91,41 @@ public class RoomTileManager {
|
||||
tallestItem = item;
|
||||
}
|
||||
|
||||
if (this.room.isAllowUnderpass() && result == RoomTileState.BLOCKED && tallestItem != null) {
|
||||
double walkSurface = this.getUnderpassWalkHeight(tile, items, exclude);
|
||||
if (tallestItem.getZ() - walkSurface >= RoomLayout.UNDERPASS_HEIGHT) {
|
||||
result = RoomTileState.OPEN;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the walk surface height for underpass checks.
|
||||
* Returns the floor height or the top of the highest walkable item below any blocking items.
|
||||
*/
|
||||
private double getUnderpassWalkHeight(RoomTile tile, THashSet<HabboItem> items, HabboItem exclude) {
|
||||
RoomLayout layout = this.room.getLayout();
|
||||
double walkHeight = layout != null ? layout.getHeightAtSquare(tile.x, tile.y) : 0;
|
||||
|
||||
if (items != null) {
|
||||
for (HabboItem item : items) {
|
||||
if (exclude != null && item == exclude) {
|
||||
continue;
|
||||
}
|
||||
if (item.isWalkable() || item.getBaseItem().allowWalk() || item.getBaseItem().allowSit() || item.getBaseItem().allowLay()) {
|
||||
double itemTop = item.getZ() + Item.getCurrentHeight(item);
|
||||
if (itemTop > walkHeight) {
|
||||
walkHeight = itemTop;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return walkHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the tile state based on a specific item.
|
||||
*/
|
||||
@@ -193,7 +225,22 @@ public class RoomTileManager {
|
||||
HabboItem item = this.room.getItemManager().getTopItemAt(x, y, exclude);
|
||||
if (item != null) {
|
||||
canStack = item.getBaseItem().allowStack();
|
||||
height = item.getZ() + (item.getBaseItem().allowSit() ? 0 : Item.getCurrentHeight(item));
|
||||
double itemTop = item.getZ() + (item.getBaseItem().allowSit() ? 0 : Item.getCurrentHeight(item));
|
||||
|
||||
// Underpass: if the top item is blocking but high enough to walk under, use floor height
|
||||
if (this.room.isAllowUnderpass() && !item.isWalkable() && !item.getBaseItem().allowWalk() && !item.getBaseItem().allowSit() && !item.getBaseItem().allowLay()) {
|
||||
RoomLayout layout2 = this.room.getLayout();
|
||||
RoomTile tile = layout2 != null ? layout2.getTile(x, y) : null;
|
||||
THashSet<HabboItem> allItems = tile != null ? this.room.getItemManager().getItemsAt(tile) : null;
|
||||
double walkSurface = this.getUnderpassWalkHeight(tile, allItems, exclude);
|
||||
if (item.getZ() - walkSurface >= RoomLayout.UNDERPASS_HEIGHT) {
|
||||
height = walkSurface;
|
||||
} else {
|
||||
height = itemTop;
|
||||
}
|
||||
} else {
|
||||
height = itemTop;
|
||||
}
|
||||
}
|
||||
|
||||
if (calculateHeightmap) {
|
||||
@@ -396,6 +443,14 @@ public class RoomTileManager {
|
||||
}
|
||||
}
|
||||
|
||||
// Underpass: if top item blocks but is high enough, allow walking under
|
||||
if (this.room.isAllowUnderpass() && !canWalk && topItem != null) {
|
||||
double walkSurface = this.getUnderpassWalkHeight(roomTile, items, null);
|
||||
if (topItem.getZ() - walkSurface >= RoomLayout.UNDERPASS_HEIGHT) {
|
||||
canWalk = true;
|
||||
}
|
||||
}
|
||||
|
||||
return canWalk;
|
||||
}
|
||||
|
||||
|
||||
@@ -235,7 +235,7 @@ public class RoomUnit {
|
||||
}
|
||||
}
|
||||
|
||||
HabboItem item = room.getTopItemAt(next.x, next.y);
|
||||
HabboItem item = room.getItemManager().getWalkableItemAt(next.x, next.y);
|
||||
boolean canSitNextTile = room.canSitAt(next.x, next.y);
|
||||
boolean canLayNextTile = room.canLayAt(next.x, next.y);
|
||||
|
||||
|
||||
@@ -129,6 +129,11 @@ public class RoomSettingsSaveEvent extends MessageHandler {
|
||||
room.setChatSpeed(this.packet.readInt());
|
||||
room.setChatDistance(Math.abs(this.packet.readInt()));
|
||||
room.setChatProtection(this.packet.readInt());
|
||||
|
||||
if (this.packet.bytesAvailable() > 0) {
|
||||
room.setAllowUnderpass(this.packet.readBoolean());
|
||||
}
|
||||
|
||||
room.setNeedsUpdate(true);
|
||||
|
||||
room.sendComposer(new RoomThicknessComposer(room).compose());
|
||||
|
||||
@@ -52,6 +52,7 @@ public class RoomSettingsComposer extends MessageComposer {
|
||||
this.response.appendInt(this.room.getMuteOption());
|
||||
this.response.appendInt(this.room.getKickOption());
|
||||
this.response.appendInt(this.room.getBanOption());
|
||||
this.response.appendInt(this.room.isAllowUnderpass() ? 1 : 0);
|
||||
return this.response;
|
||||
}
|
||||
|
||||
|
||||
@@ -84,6 +84,7 @@ public class PluginManager {
|
||||
Room.MUTEAREA_CAN_WHISPER = Emulator.getConfig().getBoolean("room.chat.mutearea.allow_whisper", false);
|
||||
RoomChatMessage.SAVE_ROOM_CHATS = Emulator.getConfig().getBoolean("save.room.chats", false);
|
||||
RoomLayout.MAXIMUM_STEP_HEIGHT = Emulator.getConfig().getDouble("pathfinder.step.maximum.height", 1.1);
|
||||
RoomLayout.UNDERPASS_HEIGHT = Emulator.getConfig().getDouble("pathfinder.underpass.height", 1.5);
|
||||
RoomLayout.ALLOW_FALLING = Emulator.getConfig().getBoolean("pathfinder.step.allow.falling", true);
|
||||
RoomTrade.TRADING_ENABLED = Emulator.getConfig().getBoolean("hotel.trading.enabled") && !ShutdownEmulator.instantiated;
|
||||
RoomTrade.TRADING_REQUIRES_PERK = Emulator.getConfig().getBoolean("hotel.trading.requires.perk");
|
||||
|
||||
Reference in New Issue
Block a user