feat: add room control furni and stack walk helper

This commit is contained in:
Lorenzune
2026-04-03 12:09:16 +02:00
parent f0ac59765f
commit 6ab152c47d
34 changed files with 1217 additions and 61 deletions
@@ -169,6 +169,7 @@ public class ItemManager {
this.interactionsList.add(new ItemInteraction("monsterplant_seed", InteractionMonsterPlantSeed.class));
this.interactionsList.add(new ItemInteraction("gift", InteractionGift.class));
this.interactionsList.add(new ItemInteraction("stack_helper", InteractionStackHelper.class));
this.interactionsList.add(new ItemInteraction("stack_walk_helper", InteractionStackWalkHelper.class));
this.interactionsList.add(new ItemInteraction("puzzle_box", InteractionPuzzleBox.class));
this.interactionsList.add(new ItemInteraction("hopper", InteractionHopper.class));
this.interactionsList.add(new ItemInteraction("costume_hopper", InteractionCostumeHopper.class));
@@ -198,6 +199,13 @@ public class ItemManager {
this.interactionsList.add(new ItemInteraction("youtube", InteractionYoutubeTV.class));
this.interactionsList.add(new ItemInteraction("jukebox", InteractionJukeBox.class));
this.interactionsList.add(new ItemInteraction("switch", InteractionSwitch.class));
this.interactionsList.add(new ItemInteraction("conf_invis_control", InteractionConfInvisControl.class));
this.interactionsList.add(new ItemInteraction("wf_conf_invis_control", InteractionConfInvisControl.class));
this.interactionsList.add(new ItemInteraction("wf_conf_area_hide", InteractionAreaHideControl.class));
this.interactionsList.add(new ItemInteraction("conf_area_hide", InteractionAreaHideControl.class));
this.interactionsList.add(new ItemInteraction("wf_conf_handitem_block", InteractionHanditemBlockControl.class));
this.interactionsList.add(new ItemInteraction("wf_conf_queue_speed", InteractionQueueSpeedControl.class));
this.interactionsList.add(new ItemInteraction("wf_conf_wired_disable", InteractionWiredDisableControl.class));
this.interactionsList.add(new ItemInteraction("switch_remote_control", InteractionSwitchRemoteControl.class));
this.interactionsList.add(new ItemInteraction("fx_box", InteractionFXBox.class));
this.interactionsList.add(new ItemInteraction("blackhole", InteractionBlackHole.class));
@@ -0,0 +1,172 @@
package com.eu.habbo.habbohotel.items.interactions;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.gameclients.GameClient;
import com.eu.habbo.habbohotel.items.Item;
import com.eu.habbo.habbohotel.rooms.Room;
import com.eu.habbo.habbohotel.rooms.RoomAreaHideSupport;
import com.eu.habbo.habbohotel.rooms.RoomLayout;
import com.eu.habbo.habbohotel.users.Habbo;
import com.eu.habbo.habbohotel.users.HabboItem;
import com.eu.habbo.habbohotel.wired.WiredEffectType;
import com.eu.habbo.messages.ServerMessage;
import gnu.trove.map.hash.THashMap;
import java.sql.ResultSet;
import java.sql.SQLException;
public class InteractionAreaHideControl extends InteractionCustomValues {
public static final THashMap<String, String> defaultValues = new THashMap<String, String>() {
{
this.put("state", "0");
}
{
this.put("rootX", "0");
}
{
this.put("rootY", "0");
}
{
this.put("width", "0");
}
{
this.put("length", "0");
}
{
this.put("invisibility", "0");
}
{
this.put("wallItems", "0");
}
{
this.put("invert", "0");
}
};
public InteractionAreaHideControl(ResultSet set, Item baseItem) throws SQLException {
super(set, baseItem, defaultValues);
this.normalizeValues();
}
public InteractionAreaHideControl(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) {
super(id, userId, item, extradata, limitedStack, limitedSells, defaultValues);
this.normalizeValues();
}
@Override
public void serializeExtradata(ServerMessage serverMessage) {
this.normalizeValues();
serverMessage.appendInt(5 + (this.isLimited() ? 256 : 0));
serverMessage.appendInt(8);
serverMessage.appendInt(RoomAreaHideSupport.getState(this));
serverMessage.appendInt(RoomAreaHideSupport.getRootX(this));
serverMessage.appendInt(RoomAreaHideSupport.getRootY(this));
serverMessage.appendInt(RoomAreaHideSupport.getWidth(this));
serverMessage.appendInt(RoomAreaHideSupport.getLength(this));
serverMessage.appendInt(RoomAreaHideSupport.isInvisibilityEnabled(this) ? 1 : 0);
serverMessage.appendInt(RoomAreaHideSupport.includesWallItems(this) ? 1 : 0);
serverMessage.appendInt(RoomAreaHideSupport.isInverted(this) ? 1 : 0);
if (this.isLimited()) {
serverMessage.appendInt(this.getLimitedSells());
serverMessage.appendInt(this.getLimitedStack());
}
}
@Override
public boolean isUsable() {
return true;
}
@Override
public boolean allowWiredResetState() {
return true;
}
@Override
public void onClick(GameClient client, Room room, Object[] objects) throws Exception {
if (room == null) {
return;
}
boolean wiredToggle = objects != null
&& objects.length >= 2
&& objects[1] instanceof WiredEffectType;
if (!wiredToggle) {
if (client == null || !this.canToggle(client.getHabbo(), room)) {
return;
}
}
this.values.put("state", (RoomAreaHideSupport.getState(this) == 1) ? "0" : "1");
this.normalizeValues();
this.needsUpdate(true);
Emulator.getThreading().run(this);
room.updateItem(this);
}
@Override
public void onCustomValuesSaved(Room room, GameClient client, THashMap<String, String> oldValues) {
this.normalizeValues();
}
public boolean canToggle(Habbo habbo, Room room) {
if (habbo == null || room == null) {
return false;
}
if (room.hasRights(habbo)) {
return true;
}
if (!habbo.getHabboStats().isRentingSpace()) {
return false;
}
HabboItem rentedItem = room.getHabboItem(habbo.getHabboStats().rentedItemId);
return room.getLayout() != null
&& rentedItem != null
&& RoomLayout.squareInSquare(
RoomLayout.getRectangle(
rentedItem.getX(),
rentedItem.getY(),
rentedItem.getBaseItem().getWidth(),
rentedItem.getBaseItem().getLength(),
rentedItem.getRotation()
),
RoomLayout.getRectangle(
this.getX(),
this.getY(),
this.getBaseItem().getWidth(),
this.getBaseItem().getLength(),
this.getRotation()
)
);
}
private void normalizeValues() {
this.values.put("state", booleanFlag(this.values.get("state")));
this.values.put("rootX", Integer.toString(nonNegative(this.values.get("rootX"))));
this.values.put("rootY", Integer.toString(nonNegative(this.values.get("rootY"))));
this.values.put("width", Integer.toString(nonNegative(this.values.get("width"))));
this.values.put("length", Integer.toString(nonNegative(this.values.get("length"))));
this.values.put("invisibility", booleanFlag(this.values.get("invisibility")));
this.values.put("wallItems", booleanFlag(this.values.get("wallItems")));
this.values.put("invert", booleanFlag(this.values.get("invert")));
}
private static int nonNegative(String value) {
try {
return Math.max(0, Integer.parseInt(value));
} catch (Exception ignored) {
return 0;
}
}
private static String booleanFlag(String value) {
return ("1".equals(value) || "true".equalsIgnoreCase(value)) ? "1" : "0";
}
}
@@ -0,0 +1,16 @@
package com.eu.habbo.habbohotel.items.interactions;
import com.eu.habbo.habbohotel.items.Item;
import java.sql.ResultSet;
import java.sql.SQLException;
public class InteractionConfInvisControl extends InteractionRemoteSwitchControl {
public InteractionConfInvisControl(ResultSet set, Item baseItem) throws SQLException {
super(set, baseItem);
}
public InteractionConfInvisControl(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) {
super(id, userId, item, extradata, limitedStack, limitedSells);
}
}
@@ -0,0 +1,16 @@
package com.eu.habbo.habbohotel.items.interactions;
import com.eu.habbo.habbohotel.items.Item;
import java.sql.ResultSet;
import java.sql.SQLException;
public class InteractionHanditemBlockControl extends InteractionRemoteSwitchControl {
public InteractionHanditemBlockControl(ResultSet set, Item baseItem) throws SQLException {
super(set, baseItem);
}
public InteractionHanditemBlockControl(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) {
super(id, userId, item, extradata, limitedStack, limitedSells);
}
}
@@ -0,0 +1,186 @@
package com.eu.habbo.habbohotel.items.interactions;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.gameclients.GameClient;
import com.eu.habbo.habbohotel.items.Item;
import com.eu.habbo.habbohotel.rooms.Room;
import java.sql.ResultSet;
import java.sql.SQLException;
public class InteractionQueueSpeedControl extends InteractionRemoteSwitchControl {
private static final int[] MODE_STATES = new int[]{0, 3, 6, 9};
private static final int MODE_FRAME_COUNT = 3;
private static final int BASE_FRAME_DURATION_MS = 500;
private transient volatile int animationRevision = 0;
private transient volatile int animationRoomId = 0;
private transient volatile int animationModeState = Integer.MIN_VALUE;
public InteractionQueueSpeedControl(ResultSet set, Item baseItem) throws SQLException {
super(set, baseItem);
}
public InteractionQueueSpeedControl(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) {
super(id, userId, item, extradata, limitedStack, limitedSells);
}
public static int toModeState(String extradata) {
int state = 0;
try {
state = Integer.parseInt(extradata);
} catch (NumberFormatException ignored) {
}
if (state >= 9) {
return 9;
}
if (state >= 6) {
return 6;
}
if (state >= 3) {
return 3;
}
return 0;
}
public static int toRollerSpeed(String extradata) {
int modeState = toModeState(extradata);
if (modeState >= 9) {
return 3;
}
if (modeState >= 6) {
return 2;
}
if (modeState >= 3) {
return 1;
}
return 0;
}
public static int toRollerIntervalMs(String extradata) {
return BASE_FRAME_DURATION_MS * (toRollerSpeed(extradata) + 1);
}
@Override
public void onClick(GameClient client, Room room, Object[] objects) throws Exception {
if (room == null) {
return;
}
boolean wiredToggle = objects != null
&& objects.length >= 2
&& objects[1] instanceof com.eu.habbo.habbohotel.wired.WiredEffectType;
if (!wiredToggle) {
if (client == null) {
return;
}
if (!this.canToggle(client.getHabbo(), room)) {
super.onClick(client, room, new Object[]{"QUEUE_SPEED_USE"});
return;
}
}
int nextModeState = getNextModeState(this.getExtradata());
applyModeState(room, nextModeState, true);
if (client != null) {
super.onClick(client, room, new Object[]{"TOGGLE_OVERRIDE"});
}
}
@Override
public void onPlace(Room room) {
super.onPlace(room);
this.ensureAnimationLoop(room);
}
@Override
public void onPickUp(Room room) {
this.animationRevision++;
this.animationRoomId = 0;
this.animationModeState = Integer.MIN_VALUE;
super.onPickUp(room);
}
public void ensureAnimationLoop(Room room) {
if (room == null || !room.isLoaded() || this.getRoomId() != room.getId()) {
return;
}
int modeState = toModeState(this.getExtradata());
if (this.animationRoomId == room.getId() && this.animationModeState == modeState) {
return;
}
applyModeState(room, modeState, false);
}
private void applyModeState(Room room, int modeState, boolean persistSelection) {
if (room == null) {
return;
}
this.animationRevision++;
this.animationRoomId = room.getId();
this.animationModeState = modeState;
this.setExtradata(Integer.toString(modeState));
if (persistSelection) {
this.needsUpdate(true);
}
room.updateItemState(this);
int revision = this.animationRevision;
int nextFrame = modeState + 1;
long delay = toRollerIntervalMs(Integer.toString(modeState));
Emulator.getThreading().run(() -> this.animateNextFrame(room, modeState, nextFrame, revision), delay);
}
private void animateNextFrame(Room room, int modeState, int nextFrame, int revision) {
if (room == null || !room.isLoaded() || this.getRoomId() != room.getId()) {
return;
}
if (revision != this.animationRevision || modeState != this.animationModeState) {
return;
}
int maxFrame = modeState + (MODE_FRAME_COUNT - 1);
int frame = (nextFrame > maxFrame) ? modeState : nextFrame;
this.setExtradata(Integer.toString(frame));
room.updateItemState(this);
int followingFrame = (frame >= maxFrame) ? modeState : (frame + 1);
long delay = toRollerIntervalMs(Integer.toString(modeState));
Emulator.getThreading().run(() -> this.animateNextFrame(room, modeState, followingFrame, revision), delay);
}
private static int getNextModeState(String extradata) {
int currentModeState = toModeState(extradata);
for (int index = 0; index < MODE_STATES.length; index++) {
if (MODE_STATES[index] != currentModeState) {
continue;
}
return MODE_STATES[(index + 1) % MODE_STATES.length];
}
return MODE_STATES[0];
}
}
@@ -0,0 +1,21 @@
package com.eu.habbo.habbohotel.items.interactions;
import com.eu.habbo.habbohotel.items.Item;
import java.sql.ResultSet;
import java.sql.SQLException;
public class InteractionRemoteSwitchControl extends InteractionDefault {
public InteractionRemoteSwitchControl(ResultSet set, Item baseItem) throws SQLException {
super(set, baseItem);
}
public InteractionRemoteSwitchControl(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) {
super(id, userId, item, extradata, limitedStack, limitedSells);
}
@Override
public boolean isUsable() {
return true;
}
}
@@ -0,0 +1,48 @@
package com.eu.habbo.habbohotel.items.interactions;
import com.eu.habbo.habbohotel.items.Item;
import com.eu.habbo.habbohotel.rooms.Room;
import com.eu.habbo.habbohotel.rooms.RoomUnit;
import com.eu.habbo.habbohotel.users.HabboItem;
import com.eu.habbo.messages.ServerMessage;
import java.sql.ResultSet;
import java.sql.SQLException;
public class InteractionStackWalkHelper extends HabboItem {
public InteractionStackWalkHelper(ResultSet set, Item baseItem) throws SQLException {
super(set, baseItem);
}
public InteractionStackWalkHelper(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) {
super(id, userId, item, extradata, limitedStack, limitedSells);
}
@Override
public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) {
return false;
}
@Override
public boolean isWalkable() {
return false;
}
@Override
public void onWalk(RoomUnit roomUnit, Room room, Object[] objects) throws Exception {
}
@Override
public void serializeExtradata(ServerMessage serverMessage) {
serverMessage.appendInt((this.isLimited() ? 256 : 0));
serverMessage.appendString(this.getExtradata());
super.serializeExtradata(serverMessage);
}
@Override
public boolean isUsable() {
return true;
}
}
@@ -0,0 +1,16 @@
package com.eu.habbo.habbohotel.items.interactions;
import com.eu.habbo.habbohotel.items.Item;
import java.sql.ResultSet;
import java.sql.SQLException;
public class InteractionWiredDisableControl extends InteractionRemoteSwitchControl {
public InteractionWiredDisableControl(ResultSet set, Item baseItem) throws SQLException {
super(set, baseItem);
}
public InteractionWiredDisableControl(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) {
super(id, userId, item, extradata, limitedStack, limitedSells);
}
}
@@ -2458,29 +2458,38 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
}
public void updateItem(HabboItem item) {
if (this.isLoaded()) {
if (item != null && item.getRoomId() == this.id) {
if (item.getBaseItem() != null) {
if (item.getBaseItem().getType() == FurnitureType.FLOOR) {
this.sendComposer(new FloorItemUpdateComposer(item).compose());
this.updateTiles(this.getLayout()
.getTilesAt(this.layout.getTile(item.getX(), item.getY()),
item.getBaseItem().getWidth(), item.getBaseItem().getLength(),
item.getRotation()));
} else if (item.getBaseItem().getType() == FurnitureType.WALL) {
this.sendComposer(new WallItemUpdateComposer(item).compose());
if (this.isLoaded()) {
if (item != null && item.getRoomId() == this.id) {
if (item.getBaseItem() != null) {
if (item.getBaseItem().getType() == FurnitureType.FLOOR) {
this.sendComposer(new FloorItemUpdateComposer(item).compose());
this.updateTiles(this.getLayout()
.getTilesAt(this.layout.getTile(item.getX(), item.getY()),
item.getBaseItem().getWidth(), item.getBaseItem().getLength(),
item.getRotation()));
if (RoomAreaHideSupport.isControllerItem(item)) {
RoomAreaHideSupport.sendState(this, item);
}
} else if (item.getBaseItem().getType() == FurnitureType.WALL) {
this.sendComposer(new WallItemUpdateComposer(item).compose());
}
}
}
}
}
}
public void updateItemState(HabboItem item) {
if (!item.isLimited()) {
this.sendComposer(new ItemStateComposer(item).compose());
} else {
this.sendComposer(new FloorItemUpdateComposer(item).compose());
}
if (item != null && RoomAreaHideSupport.isControllerItem(item)) {
this.updateItem(item);
return;
}
if (!item.isLimited()) {
this.sendComposer(new ItemStateComposer(item).compose());
} else {
this.sendComposer(new FloorItemUpdateComposer(item).compose());
}
if (item.getBaseItem().getType() == FurnitureType.FLOOR) {
if (this.layout == null) {
@@ -2495,6 +2504,16 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
((InteractionMultiHeight) item).updateUnitsOnItem(this);
}
}
if (item.getBaseItem().getType() == FurnitureType.FLOOR
&& (RoomConfInvisSupport.isControllerItem(item) || RoomConfInvisSupport.isTarget(item))) {
RoomConfInvisSupport.sendState(this);
}
if (item.getBaseItem().getType() == FurnitureType.FLOOR
&& RoomHanditemBlockSupport.isControllerItem(item)) {
RoomHanditemBlockSupport.sendState(this);
}
}
public int getUserFurniCount(int userId) {
@@ -0,0 +1,100 @@
package com.eu.habbo.habbohotel.rooms;
import com.eu.habbo.habbohotel.gameclients.GameClient;
import com.eu.habbo.habbohotel.items.FurnitureType;
import com.eu.habbo.habbohotel.items.interactions.InteractionAreaHideControl;
import com.eu.habbo.habbohotel.users.HabboItem;
import com.eu.habbo.messages.outgoing.rooms.items.AreaHideComposer;
public final class RoomAreaHideSupport {
private RoomAreaHideSupport() {
}
public static boolean isControllerItem(HabboItem item) {
return item instanceof InteractionAreaHideControl
|| hasInteractionName(item, "wf_conf_area_hide")
|| hasInteractionName(item, "conf_area_hide");
}
public static boolean isControllerActive(HabboItem item) {
return isControllerItem(item) && getState(item) == 1;
}
public static int getState(HabboItem item) {
return Math.min(1, readIntValue(item, "state", 0));
}
public static int getRootX(HabboItem item) {
return readIntValue(item, "rootX", 0);
}
public static int getRootY(HabboItem item) {
return readIntValue(item, "rootY", 0);
}
public static int getWidth(HabboItem item) {
return readIntValue(item, "width", 0);
}
public static int getLength(HabboItem item) {
return readIntValue(item, "length", 0);
}
public static boolean isInvisibilityEnabled(HabboItem item) {
return readIntValue(item, "invisibility", 0) == 1;
}
public static boolean includesWallItems(HabboItem item) {
return readIntValue(item, "wallItems", 0) == 1;
}
public static boolean isInverted(HabboItem item) {
return readIntValue(item, "invert", 0) == 1;
}
public static void sendState(Room room, HabboItem item) {
if (room == null || item == null || !isControllerItem(item)) {
return;
}
room.sendComposer(new AreaHideComposer(item).compose());
}
public static void sendState(Room room, GameClient client) {
if (room == null || client == null) {
return;
}
for (HabboItem item : room.getFloorItems()) {
if (!isControllerActive(item)) {
continue;
}
client.sendResponse(new AreaHideComposer(item).compose());
}
}
private static int readIntValue(HabboItem item, String key, int fallback) {
if (!(item instanceof InteractionAreaHideControl) || key == null) {
return fallback;
}
InteractionAreaHideControl areaHide = (InteractionAreaHideControl) item;
String value = areaHide.values.get(key);
try {
return Math.max(0, Integer.parseInt(value));
} catch (Exception ignored) {
return fallback;
}
}
private static boolean hasInteractionName(HabboItem item, String interactionName) {
return item != null
&& item.getBaseItem() != null
&& item.getBaseItem().getType() == FurnitureType.FLOOR
&& item.getBaseItem().getInteractionType() != null
&& item.getBaseItem().getInteractionType().getName() != null
&& item.getBaseItem().getInteractionType().getName().equalsIgnoreCase(interactionName);
}
}
@@ -0,0 +1,107 @@
package com.eu.habbo.habbohotel.rooms;
import com.eu.habbo.habbohotel.gameclients.GameClient;
import com.eu.habbo.habbohotel.items.FurnitureType;
import com.eu.habbo.habbohotel.items.interactions.InteractionConfInvisControl;
import com.eu.habbo.habbohotel.users.HabboItem;
import com.eu.habbo.messages.outgoing.rooms.items.ConfInvisStateComposer;
import gnu.trove.list.array.TIntArrayList;
import java.util.regex.Pattern;
public final class RoomConfInvisSupport {
private RoomConfInvisSupport() {
}
public static boolean isControllerItem(HabboItem item) {
return item instanceof InteractionConfInvisControl
|| hasInteractionName(item, "wf_conf_invis_control");
}
public static boolean isControllerActive(HabboItem item) {
return isControllerItem(item) && "1".equals(item.getExtradata());
}
public static boolean isTarget(HabboItem item) {
return item != null
&& item.getBaseItem() != null
&& item.getBaseItem().getType() == FurnitureType.FLOOR
&& hasCustomParamToken(item.getBaseItem().getCustomParams(), "is_invisible");
}
public static TIntArrayList collectHiddenFloorItemIds(Room room) {
TIntArrayList hiddenItemIds = new TIntArrayList();
if (room == null) {
return hiddenItemIds;
}
if (!hasActiveController(room)) {
return hiddenItemIds;
}
for (HabboItem item : room.getFloorItems()) {
if (isTarget(item)) {
hiddenItemIds.add(item.getId());
}
}
return hiddenItemIds;
}
public static boolean hasActiveController(Room room) {
if (room == null) {
return false;
}
for (HabboItem item : room.getFloorItems()) {
if (isControllerActive(item)) {
return true;
}
}
return false;
}
public static void sendState(Room room) {
if (room == null) {
return;
}
room.sendComposer(new ConfInvisStateComposer(room).compose());
}
public static void sendState(Room room, GameClient client) {
if (room == null || client == null) {
return;
}
client.sendResponse(new ConfInvisStateComposer(room).compose());
}
private static boolean hasCustomParamToken(String value, String token) {
if (value == null || token == null) {
return false;
}
String normalized = value.trim().toLowerCase();
if (normalized.isEmpty()) {
return false;
}
Pattern pattern = Pattern.compile("(^|[^a-z0-9_])" + Pattern.quote(token.toLowerCase()) + "($|[^a-z0-9_])");
return pattern.matcher(normalized).find();
}
private static boolean hasInteractionName(HabboItem item, String interactionName) {
if (item == null || item.getBaseItem() == null || item.getBaseItem().getInteractionType() == null || interactionName == null) {
return false;
}
String currentInteractionName = item.getBaseItem().getInteractionType().getName();
return currentInteractionName != null && currentInteractionName.equalsIgnoreCase(interactionName);
}
}
@@ -377,7 +377,8 @@ public class RoomCycleManager {
* Processes roller cycle.
*/
private void processRollers(THashSet<RoomUnit> updatedUnit) {
int rollerSpeed = this.room.getRollerSpeed();
Integer controlledRollerSpeed = RoomQueueSpeedControlSupport.getEffectiveRollerSpeed(this.room);
int rollerSpeed = (controlledRollerSpeed != null) ? controlledRollerSpeed : this.room.getRollerSpeed();
if (rollerSpeed != -1 && this.rollerCycle >= rollerSpeed) {
this.rollerCycle = 0;
this.room.getRollerManager().processRollerCycle(updatedUnit, this.cycleTimestamp);
@@ -0,0 +1,65 @@
package com.eu.habbo.habbohotel.rooms;
import com.eu.habbo.habbohotel.items.interactions.InteractionHanditemBlockControl;
import com.eu.habbo.habbohotel.users.HabboItem;
import com.eu.habbo.habbohotel.gameclients.GameClient;
import com.eu.habbo.messages.outgoing.rooms.items.HanditemBlockStateComposer;
public final class RoomHanditemBlockSupport {
private static final String CONTROLLER_INTERACTION = "wf_conf_handitem_block";
private RoomHanditemBlockSupport() {
}
public static boolean isHanditemBlocked(Room room) {
if (room == null) {
return false;
}
for (HabboItem item : room.getFloorItems()) {
if (isActiveController(item)) {
return true;
}
}
return false;
}
public static boolean isActiveController(HabboItem item) {
return isControllerItem(item) && "1".equals(item.getExtradata());
}
public static boolean isControllerItem(HabboItem item) {
if (item == null || item.getBaseItem() == null) {
return false;
}
if (item instanceof InteractionHanditemBlockControl) {
return true;
}
if (item.getBaseItem().getInteractionType() == null) {
return false;
}
String interactionName = item.getBaseItem().getInteractionType().getName();
return interactionName != null && interactionName.equalsIgnoreCase(CONTROLLER_INTERACTION);
}
public static void sendState(Room room) {
if (room == null) {
return;
}
room.sendComposer(new HanditemBlockStateComposer(room).compose());
}
public static void sendState(Room room, GameClient client) {
if (room == null || client == null) {
return;
}
client.sendResponse(new HanditemBlockStateComposer(room).compose());
}
}
@@ -1009,6 +1009,18 @@ public class RoomItemManager {
if (item.getBaseItem().getType() == FurnitureType.FLOOR) {
this.room.sendComposer(new RemoveFloorItemComposer(item).compose());
if (RoomConfInvisSupport.isControllerItem(item) || RoomConfInvisSupport.isTarget(item)) {
RoomConfInvisSupport.sendState(this.room);
}
if (RoomAreaHideSupport.isControllerItem(item)) {
RoomAreaHideSupport.sendState(this.room, item);
}
if (RoomHanditemBlockSupport.isControllerItem(item)) {
RoomHanditemBlockSupport.sendState(this.room);
}
THashSet<RoomTile> updatedTiles = this.room.getLayout().getTilesAt(
this.room.getLayout().getTile(item.getX(), item.getY()),
item.getBaseItem().getWidth(),
@@ -1296,13 +1308,75 @@ public class RoomItemManager {
/**
* Checks if furniture fits at a location with unit check option.
*/
private boolean isStackPlacementBypassItem(HabboItem item) {
return item instanceof InteractionStackHelper
|| item instanceof InteractionTileWalkMagic
|| item instanceof InteractionStackWalkHelper;
}
private boolean shouldPinStackHelperToFloor(HabboItem item) {
return item instanceof InteractionStackHelper || item instanceof InteractionTileWalkMagic;
}
private boolean isStackHeightHelper(HabboItem item) {
return item instanceof InteractionStackHelper
|| item instanceof InteractionTileWalkMagic
|| item instanceof InteractionStackWalkHelper;
}
private HabboItem findStackHeightHelperAt(RoomTile tile, HabboItem exclude) {
if (tile == null) {
return null;
}
for (HabboItem helper : this.getItemsAt(tile)) {
if (helper != exclude && this.isStackHeightHelper(helper)) {
return helper;
}
}
return null;
}
private double getMinimumTileHeight(THashSet<RoomTile> occupiedTiles) {
double minimumHeight = 0.0D;
for (RoomTile occupiedTile : occupiedTiles) {
minimumHeight = Math.max(minimumHeight, this.room.getLayout().getHeightAtSquare(occupiedTile.x, occupiedTile.y));
}
return minimumHeight;
}
private double getConfiguredStackWalkHelperHeight(HabboItem item, THashSet<RoomTile> occupiedTiles) {
double height = 0.0D;
try {
if (item.getExtradata() != null && !item.getExtradata().isEmpty()) {
height = Double.parseDouble(item.getExtradata()) / 100.0D;
}
} catch (NumberFormatException ignored) {
}
return Math.max(height, this.getMinimumTileHeight(occupiedTiles));
}
private double resolveStackWalkHelperHeight(HabboItem item, RoomTile tile, THashSet<RoomTile> occupiedTiles) {
HabboItem helper = this.findStackHeightHelperAt(tile, item);
if (helper != null) {
return Math.max(helper.getZ(), this.getMinimumTileHeight(occupiedTiles));
}
return this.getConfiguredStackWalkHelperHeight(item, occupiedTiles);
}
public FurnitureMovementError furnitureFitsAt(RoomTile tile, HabboItem item, int rotation, boolean checkForUnits) {
RoomLayout layout = this.room.getLayout();
if (!layout.fitsOnMap(tile, item.getBaseItem().getWidth(), item.getBaseItem().getLength(), rotation)) {
return FurnitureMovementError.INVALID_MOVE;
}
if (item instanceof InteractionStackHelper || item instanceof InteractionTileWalkMagic) {
if (this.isStackPlacementBypassItem(item)) {
return FurnitureMovementError.NONE;
}
@@ -1354,7 +1428,7 @@ public class RoomItemManager {
return FurnitureMovementError.INVALID_MOVE;
}
if (item instanceof InteractionStackHelper || item instanceof InteractionTileWalkMagic) {
if (this.isStackPlacementBypassItem(item)) {
return FurnitureMovementError.NONE;
}
@@ -1463,6 +1537,18 @@ public class RoomItemManager {
this.room.sendComposer(
new AddFloorItemComposer(item, this.getFurniOwnerName(item.getUserId())).compose());
if (RoomConfInvisSupport.isControllerItem(item) || RoomConfInvisSupport.isTarget(item)) {
RoomConfInvisSupport.sendState(this.room);
}
if (RoomAreaHideSupport.isControllerItem(item)) {
RoomAreaHideSupport.sendState(this.room, item);
}
if (RoomHanditemBlockSupport.isControllerItem(item)) {
RoomHanditemBlockSupport.sendState(this.room);
}
for (RoomTile t : occupiedTiles) {
this.room.updateHabbosAt(t.x, t.y);
this.room.updateBotsAt(t.x, t.y);
@@ -1530,9 +1616,7 @@ public class RoomItemManager {
rotation %= 8;
boolean magicTile =
item instanceof InteractionStackHelper ||
item instanceof InteractionTileWalkMagic;
boolean magicTile = this.isStackPlacementBypassItem(item);
THashSet<RoomTile> occupiedTiles = layout.getTilesAt(
tile,
@@ -1595,9 +1679,11 @@ public class RoomItemManager {
item.setY(tile.y);
item.setZ(z);
if (magicTile) {
if (this.shouldPinStackHelperToFloor(item)) {
item.setZ(tile.z);
item.setExtradata("" + (item.getZ() * 100));
} else if (item instanceof InteractionStackWalkHelper) {
item.setZ(this.resolveStackWalkHelperHeight(item, tile, occupiedTiles));
}
if (item.getZ() > Room.MAXIMUM_FURNI_HEIGHT) {
@@ -1689,9 +1775,7 @@ public class RoomItemManager {
rotation %= 8;
boolean magicTile =
item instanceof InteractionStackHelper ||
item instanceof InteractionTileWalkMagic;
boolean magicTile = this.isStackPlacementBypassItem(item);
THashSet<RoomTile> occupiedTiles = layout.getTilesAt(
tile,
@@ -1751,9 +1835,11 @@ public class RoomItemManager {
item.setY(tile.y);
item.setZ(z);
if (magicTile) {
if (this.shouldPinStackHelperToFloor(item)) {
item.setZ(tile.z);
item.setExtradata("" + (item.getZ() * 100));
} else if (item instanceof InteractionStackWalkHelper) {
item.setZ(this.resolveStackWalkHelperHeight(item, tile, occupiedTiles));
}
if (item.getZ() > Room.MAXIMUM_FURNI_HEIGHT) {
@@ -1845,10 +1931,9 @@ public class RoomItemManager {
pluginHelper = event.hasPluginHelper();
}
boolean magicTile = item instanceof InteractionStackHelper || item instanceof InteractionTileWalkMagic;
boolean magicTile = this.isStackPlacementBypassItem(item);
java.util.Optional<HabboItem> stackHelper = this.getItemsAt(tile).stream()
.filter(i -> i instanceof InteractionStackHelper).findAny();
HabboItem stackHelper = this.findStackHeightHelperAt(tile, item);
// Check if can be placed at new position
THashSet<RoomTile> occupiedTiles = layout.getTilesAt(tile, item.getBaseItem().getWidth(),
@@ -1858,7 +1943,7 @@ public class RoomItemManager {
HabboItem topItem = this.getTopItemAt(occupiedTiles, null);
if (!stackHelper.isPresent() && !pluginHelper) {
if (stackHelper == null && !pluginHelper) {
if (oldLocation != tile) {
for (RoomTile t : occupiedTiles) {
HabboItem tileTopItem = this.getTopItemAt(t.x, t.y);
@@ -1915,7 +2000,7 @@ public class RoomItemManager {
}
}
if ((!stackHelper.isPresent() && topItem != null && topItem != item && !topItem.getBaseItem()
if ((stackHelper == null && topItem != null && topItem != item && !topItem.getBaseItem()
.allowStack()) || (topItem != null && topItem != item
&& topItem.getZ() + Item.getCurrentHeight(topItem) + Item.getCurrentHeight(item)
> Room.MAXIMUM_FURNI_HEIGHT)) {
@@ -1927,9 +2012,10 @@ public class RoomItemManager {
// Place at new position
double height;
if (stackHelper.isPresent()) {
height = stackHelper.get().getExtradata().isEmpty() ? Double.parseDouble("0.0")
: (Double.parseDouble(stackHelper.get().getExtradata()) / 100);
if (stackHelper != null) {
height = stackHelper.getZ();
} else if (item instanceof InteractionStackWalkHelper) {
height = this.resolveStackWalkHelperHeight(item, tile, occupiedTiles);
} else if (item == topItem) {
height = item.getZ();
} else if (magicTile) {
@@ -1980,7 +2066,7 @@ public class RoomItemManager {
item.setX(tile.x);
item.setY(tile.y);
item.setZ(height);
if (magicTile) {
if (this.shouldPinStackHelperToFloor(item)) {
item.setZ(tile.z);
item.setExtradata("" + item.getZ() * 100);
}
@@ -2054,10 +2140,9 @@ public class RoomItemManager {
pluginHelper = event.hasPluginHelper();
}
boolean magicTile = item instanceof InteractionStackHelper || item instanceof InteractionTileWalkMagic;
boolean magicTile = this.isStackPlacementBypassItem(item);
java.util.Optional<HabboItem> stackHelper = this.getItemsAt(tile).stream()
.filter(i -> i instanceof InteractionStackHelper).findAny();
HabboItem stackHelper = this.findStackHeightHelperAt(tile, item);
THashSet<RoomTile> occupiedTiles = layout.getTilesAt(tile, item.getBaseItem().getWidth(),
item.getBaseItem().getLength(), rotation);
@@ -2066,7 +2151,7 @@ public class RoomItemManager {
HabboItem topItem = this.getTopPhysicsItemAt(occupiedTiles, null, physics);
if (!stackHelper.isPresent() && !pluginHelper) {
if (stackHelper == null && !pluginHelper) {
if (oldLocation != tile) {
for (RoomTile t : occupiedTiles) {
HabboItem tileTopItem = this.getTopPhysicsItemAt(t.x, t.y, item, physics);
@@ -2118,7 +2203,7 @@ public class RoomItemManager {
}
}
if ((!stackHelper.isPresent() && topItem != null && topItem != item && !topItem.getBaseItem()
if ((stackHelper == null && topItem != null && topItem != item && !topItem.getBaseItem()
.allowStack()) || (topItem != null && topItem != item
&& topItem.getZ() + Item.getCurrentHeight(topItem) + Item.getCurrentHeight(item)
> Room.MAXIMUM_FURNI_HEIGHT)) {
@@ -2129,9 +2214,10 @@ public class RoomItemManager {
double height;
if (stackHelper.isPresent()) {
height = stackHelper.get().getExtradata().isEmpty() ? Double.parseDouble("0.0")
: (Double.parseDouble(stackHelper.get().getExtradata()) / 100);
if (stackHelper != null) {
height = stackHelper.getZ();
} else if (item instanceof InteractionStackWalkHelper) {
height = this.resolveStackWalkHelperHeight(item, tile, occupiedTiles);
} else if (item == topItem) {
height = item.getZ();
} else if (magicTile) {
@@ -2182,7 +2268,7 @@ public class RoomItemManager {
item.setX(tile.x);
item.setY(tile.y);
item.setZ(height);
if (magicTile) {
if (this.shouldPinStackHelperToFloor(item)) {
item.setZ(tile.z);
item.setExtradata("" + item.getZ() * 100);
}
@@ -2237,7 +2323,7 @@ public class RoomItemManager {
* Slides furniture to a new position.
*/
public FurnitureMovementError slideFurniTo(HabboItem item, RoomTile tile, int rotation) {
boolean magicTile = item instanceof InteractionStackHelper;
boolean magicTile = this.isStackPlacementBypassItem(item);
RoomLayout layout = this.room.getLayout();
@@ -2257,9 +2343,11 @@ public class RoomItemManager {
item.setRotation(rotation);
// Place at new position
if (magicTile) {
if (this.shouldPinStackHelperToFloor(item)) {
item.setZ(tile.z);
item.setExtradata("" + item.getZ() * 100);
} else if (item instanceof InteractionStackWalkHelper) {
item.setZ(this.resolveStackWalkHelperHeight(item, tile, occupiedTiles));
}
if (item.getZ() > Room.MAXIMUM_FURNI_HEIGHT) {
item.setZ(Room.MAXIMUM_FURNI_HEIGHT);
@@ -2410,12 +2498,17 @@ public class RoomItemManager {
return height;
}
double helperHeight = Double.NEGATIVE_INFINITY;
for (HabboItem item : this.getPhysicsItemsAt(tile, exclude, physics)) {
if (item instanceof InteractionStackHelper || item instanceof InteractionTileWalkMagic) {
return item.getZ();
if (item instanceof InteractionStackHelper || item instanceof InteractionTileWalkMagic || item instanceof InteractionStackWalkHelper) {
helperHeight = Math.max(helperHeight, item.getZ());
}
}
if (helperHeight != Double.NEGATIVE_INFINITY) {
return helperHeight;
}
HabboItem topItem = this.getTopPhysicsItemAt(x, y, exclude, physics);
if (topItem != null) {
return topItem.getZ() + (topItem.getBaseItem().allowSit() ? 0 : Item.getCurrentHeight(topItem));
@@ -34,6 +34,8 @@ import com.eu.habbo.messages.outgoing.polls.PollStartComposer;
import com.eu.habbo.messages.outgoing.polls.infobus.SimplePollAnswersComposer;
import com.eu.habbo.messages.outgoing.polls.infobus.SimplePollStartComposer;
import com.eu.habbo.messages.outgoing.rooms.*;
import com.eu.habbo.messages.outgoing.rooms.items.ConfInvisStateComposer;
import com.eu.habbo.messages.outgoing.rooms.items.HanditemBlockStateComposer;
import com.eu.habbo.messages.outgoing.rooms.items.RoomFloorItemsComposer;
import com.eu.habbo.messages.outgoing.rooms.items.RoomWallItemsComposer;
import com.eu.habbo.messages.outgoing.rooms.pets.RoomPetComposer;
@@ -886,6 +888,10 @@ public class RoomManager {
floorItems.clear();
}
habbo.getClient().sendResponse(new ConfInvisStateComposer(room).compose());
RoomAreaHideSupport.sendState(room, habbo.getClient());
habbo.getClient().sendResponse(new HanditemBlockStateComposer(room).compose());
if (!room.getCurrentPets().isEmpty()) {
habbo.getClient().sendResponse(new RoomPetComposer(room.getCurrentPets()));
for (Pet pet : room.getCurrentPets().valueCollection()) {
@@ -0,0 +1,77 @@
package com.eu.habbo.habbohotel.rooms;
import com.eu.habbo.habbohotel.items.interactions.InteractionQueueSpeedControl;
import com.eu.habbo.habbohotel.items.interactions.InteractionRoller;
import com.eu.habbo.habbohotel.users.HabboItem;
public final class RoomQueueSpeedControlSupport {
private static final String CONTROLLER_INTERACTION = "wf_conf_queue_speed";
private RoomQueueSpeedControlSupport() {
}
public static Integer getEffectiveRollerSpeed(Room room) {
HabboItem controller = getControllerItem(room);
return controller != null ? InteractionQueueSpeedControl.toRollerSpeed(controller.getExtradata()) : null;
}
public static int getEffectiveRollerIntervalMs(Room room) {
Integer effectiveRollerSpeed = getEffectiveRollerSpeed(room);
if (effectiveRollerSpeed != null) {
return toRollerIntervalMs(effectiveRollerSpeed);
}
if (room == null) {
return InteractionRoller.DELAY;
}
return toRollerIntervalMs(room.getRollerSpeed());
}
private static int toRollerIntervalMs(int rollerSpeed) {
if (rollerSpeed < 0) {
return InteractionRoller.DELAY;
}
return (rollerSpeed + 1) * 500;
}
private static boolean isControllerItem(HabboItem item) {
if (item == null || item.getBaseItem() == null) {
return false;
}
if (item instanceof InteractionQueueSpeedControl) {
return true;
}
if (item.getBaseItem().getInteractionType() == null) {
return false;
}
String interactionName = item.getBaseItem().getInteractionType().getName();
return interactionName != null && interactionName.equalsIgnoreCase(CONTROLLER_INTERACTION);
}
private static HabboItem getControllerItem(Room room) {
if (room == null) {
return null;
}
for (HabboItem item : room.getFloorItems()) {
if (!isControllerItem(item)) {
continue;
}
if (item instanceof InteractionQueueSpeedControl) {
((InteractionQueueSpeedControl) item).ensureAnimationLoop(room);
}
return item;
}
return null;
}
}
@@ -354,7 +354,7 @@ public class RoomRollerManager {
LOGGER.error("Caught exception", e);
}
}
}, this.room.getRollerSpeed() == 0 ? 250 : InteractionRoller.DELAY);
}, RoomQueueSpeedControlSupport.getEffectiveRollerIntervalMs(this.room));
}
}
@@ -4,6 +4,7 @@ import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.bots.Bot;
import com.eu.habbo.habbohotel.items.Item;
import com.eu.habbo.habbohotel.items.interactions.InteractionStackHelper;
import com.eu.habbo.habbohotel.items.interactions.InteractionStackWalkHelper;
import com.eu.habbo.habbohotel.items.interactions.InteractionTileWalkMagic;
import com.eu.habbo.habbohotel.users.HabboItem;
import com.eu.habbo.plugin.events.furniture.FurnitureStackHeightEvent;
@@ -149,7 +150,7 @@ public class RoomTileManager {
result = overriddenState;
}
if (this.room.getItemManager().getItemsAt(tile).stream().anyMatch(i -> i instanceof InteractionTileWalkMagic)) {
if (this.room.getItemManager().getItemsAt(tile).stream().anyMatch(i -> i instanceof InteractionTileWalkMagic || i instanceof InteractionStackWalkHelper)) {
result = RoomTileState.OPEN;
}
@@ -211,14 +212,20 @@ public class RoomTileManager {
boolean canStack = true;
THashSet<HabboItem> stackHelpers = this.room.getItemManager().getItemsAt(InteractionStackHelper.class, x, y);
stackHelpers.addAll(this.room.getItemManager().getItemsAt(InteractionStackWalkHelper.class, x, y));
stackHelpers.addAll(this.room.getItemManager().getItemsAt(InteractionTileWalkMagic.class, x, y));
if (stackHelpers.size() > 0) {
double helperHeight = Double.NEGATIVE_INFINITY;
for (HabboItem item : stackHelpers) {
if (item == exclude) {
continue;
}
return calculateHeightmap ? item.getZ() * 256.0D : item.getZ();
helperHeight = Math.max(helperHeight, item.getZ());
}
if (helperHeight != Double.NEGATIVE_INFINITY) {
return calculateHeightmap ? helperHeight * 256.0D : helperHeight;
}
}
@@ -425,6 +432,10 @@ public class RoomTileManager {
HabboItem topItem = null;
boolean canWalk = true;
THashSet<HabboItem> items = this.room.getItemManager().getItemsAt(roomTile);
if (items != null && items.stream().anyMatch(item -> item instanceof InteractionTileWalkMagic || item instanceof InteractionStackWalkHelper)) {
return true;
}
if (items != null) {
for (HabboItem item : items) {
if (topItem == null) {
@@ -4,6 +4,7 @@ import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.bots.Bot;
import com.eu.habbo.habbohotel.items.Item;
import com.eu.habbo.habbohotel.items.interactions.InteractionTileWalkMagic;
import com.eu.habbo.habbohotel.items.interactions.InteractionStackWalkHelper;
import com.eu.habbo.habbohotel.items.interactions.InteractionWater;
import com.eu.habbo.habbohotel.items.interactions.InteractionWaterItem;
import com.eu.habbo.habbohotel.items.interactions.interfaces.ConditionalGate;
@@ -325,7 +326,7 @@ public class RoomUnit {
}
Optional<HabboItem> stackHelper = room.getItemsAt(next).stream()
.filter(i -> i instanceof InteractionTileWalkMagic).findAny();
.filter(i -> i instanceof InteractionTileWalkMagic || i instanceof InteractionStackWalkHelper).findAny();
if (stackHelper.isPresent()) {
zHeight = stackHelper.get().getZ();
}
@@ -0,0 +1,47 @@
package com.eu.habbo.habbohotel.rooms;
import com.eu.habbo.habbohotel.items.interactions.InteractionWiredDisableControl;
import com.eu.habbo.habbohotel.users.HabboItem;
public final class RoomWiredDisableSupport {
private static final String CONTROLLER_INTERACTION = "wf_conf_wired_disable";
private RoomWiredDisableSupport() {
}
public static boolean isWiredDisabled(Room room) {
if (room == null) {
return false;
}
for (HabboItem item : room.getFloorItems()) {
if (isActiveController(item)) {
return true;
}
}
return false;
}
public static boolean isActiveController(HabboItem item) {
return isControllerItem(item) && "1".equals(item.getExtradata());
}
public static boolean isControllerItem(HabboItem item) {
if (item == null || item.getBaseItem() == null) {
return false;
}
if (item instanceof InteractionWiredDisableControl) {
return true;
}
if (item.getBaseItem().getInteractionType() == null) {
return false;
}
String interactionName = item.getBaseItem().getInteractionType().getName();
return interactionName != null && interactionName.equalsIgnoreCase(CONTROLLER_INTERACTION);
}
}
@@ -16,6 +16,7 @@ import com.eu.habbo.habbohotel.items.interactions.wired.extra.WiredExtraOrEval;
import com.eu.habbo.habbohotel.items.interactions.wired.extra.WiredExtraRandom;
import com.eu.habbo.habbohotel.items.interactions.wired.extra.WiredExtraUnseen;
import com.eu.habbo.habbohotel.rooms.Room;
import com.eu.habbo.habbohotel.rooms.RoomWiredDisableSupport;
import com.eu.habbo.habbohotel.rooms.RoomTile;
import com.eu.habbo.habbohotel.rooms.RoomUnit;
import com.eu.habbo.habbohotel.users.Habbo;
@@ -71,6 +72,9 @@ public class WiredHandler {
if (room == null)
return false;
if (RoomWiredDisableSupport.isWiredDisabled(room))
return false;
if (!room.isLoaded())
return false;
@@ -118,6 +122,9 @@ public class WiredHandler {
if (room == null)
return false;
if (RoomWiredDisableSupport.isWiredDisabled(room))
return false;
if (!room.isLoaded())
return false;
@@ -160,6 +167,9 @@ public class WiredHandler {
long millis = System.currentTimeMillis();
LegacyExecutionPlan executionPlan = new LegacyExecutionPlan();
if (RoomWiredDisableSupport.isWiredDisabled(room))
return false;
if(handle(trigger, roomUnit, room, stuff, executionPlan)) {
triggerEffects(executionPlan.effects, roomUnit, room, stuff, millis, executionPlan.executeInOrder);
return true;
@@ -10,6 +10,7 @@ import com.eu.habbo.habbohotel.items.interactions.wired.effects.WiredEffectTrigg
import com.eu.habbo.habbohotel.items.interactions.wired.extra.WiredExtraExecutionLimit;
import com.eu.habbo.habbohotel.items.interactions.wired.triggers.WiredTriggerHabboClicksUser;
import com.eu.habbo.habbohotel.rooms.Room;
import com.eu.habbo.habbohotel.rooms.RoomWiredDisableSupport;
import com.eu.habbo.habbohotel.rooms.RoomTile;
import com.eu.habbo.habbohotel.rooms.RoomUnit;
import com.eu.habbo.habbohotel.users.Habbo;
@@ -231,6 +232,10 @@ public final class WiredManager {
if (!isEnabled() || engine == null) {
return false;
}
if (event == null || RoomWiredDisableSupport.isWiredDisabled(event.getRoom())) {
return false;
}
return engine.handleEvent(event);
}
@@ -348,6 +353,10 @@ public final class WiredManager {
return false;
}
if (RoomWiredDisableSupport.isWiredDisabled(room)) {
return false;
}
WiredEvent event = WiredEvents.userSays(room, user, message, chatType, chatStyle);
return engine.shouldSuppressUserSaysOutput(event);
}
@@ -77,6 +77,7 @@ public class RoomPlaceItemEvent extends MessageHandler {
if ((rentSpace != null || buildArea != null) && !room.hasRights(this.client.getHabbo())) {
if (item instanceof InteractionRoller ||
item instanceof InteractionStackHelper ||
item instanceof InteractionStackWalkHelper ||
item instanceof InteractionWired ||
item instanceof InteractionBackgroundToner ||
item instanceof InteractionRoomAds ||
@@ -1,6 +1,7 @@
package com.eu.habbo.messages.incoming.rooms.items;
import com.eu.habbo.habbohotel.items.interactions.InteractionStackHelper;
import com.eu.habbo.habbohotel.items.interactions.InteractionStackWalkHelper;
import com.eu.habbo.habbohotel.items.interactions.InteractionTileWalkMagic;
import com.eu.habbo.habbohotel.rooms.Room;
import com.eu.habbo.habbohotel.rooms.RoomTile;
@@ -21,7 +22,7 @@ public class SetStackHelperHeightEvent extends MessageHandler {
if (this.client.getHabbo().getHabboInfo().getId() == this.client.getHabbo().getHabboInfo().getCurrentRoom().getOwnerId() || this.client.getHabbo().getHabboInfo().getCurrentRoom().hasRights(this.client.getHabbo())) {
HabboItem item = this.client.getHabbo().getHabboInfo().getCurrentRoom().getHabboItem(itemId);
if (item instanceof InteractionStackHelper || item instanceof InteractionTileWalkMagic) {
if (item instanceof InteractionStackHelper || item instanceof InteractionTileWalkMagic || item instanceof InteractionStackWalkHelper) {
Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom();
RoomTile itemTile = room.getLayout().getTile(item.getX(), item.getY());
double stackerHeight = this.packet.readInt();
@@ -51,7 +52,7 @@ public class SetStackHelperHeightEvent extends MessageHandler {
item.setExtradata((int) (height * 100) + "");
item.needsUpdate(true);
if (item instanceof InteractionTileWalkMagic) {
if (item instanceof InteractionTileWalkMagic || item instanceof InteractionStackWalkHelper) {
for (RoomTile t : tiles) {
this.client.getHabbo().getHabboInfo().getCurrentRoom().updateHabbosAt(t.x, t.y);
this.client.getHabbo().getHabboInfo().getCurrentRoom().updateBotsAt(t.x, t.y);
@@ -2,6 +2,7 @@ package com.eu.habbo.messages.incoming.rooms.users;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.rooms.Room;
import com.eu.habbo.habbohotel.rooms.RoomHanditemBlockSupport;
import com.eu.habbo.habbohotel.users.Habbo;
import com.eu.habbo.messages.incoming.MessageHandler;
import com.eu.habbo.threading.runnables.HabboGiveHandItemToHabbo;
@@ -18,6 +19,10 @@ public class RoomUserGiveHandItemEvent extends MessageHandler {
Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom();
if (room != null) {
if (RoomHanditemBlockSupport.isHanditemBlocked(room)) {
return;
}
Habbo target = room.getHabbo(userId);
if (target != null) {
@@ -123,6 +123,8 @@ public class Outgoing {
public final static int WiredMonitorDataComposer = 5101; // CUSTOM
public final static int WiredRoomSettingsDataComposer = 5102; // CUSTOM
public final static int WiredUserVariablesDataComposer = 5103; // CUSTOM
public final static int ConfInvisStateComposer = 5104; // CUSTOM
public final static int AreaHideComposer = 6001; // CUSTOM
public final static int RoomPaintComposer = 2454; // PRODUCTION-201611291003-338511768
public final static int MarketplaceConfigComposer = 1823; // PRODUCTION-201611291003-338511768
public final static int AddBotComposer = 1352; // PRODUCTION-201611291003-338511768
@@ -328,6 +330,7 @@ public class Outgoing {
public final static int VerifyMobilePhoneCodeWindowComposer = 800; // PRODUCTION-201611291003-338511768
public final static int VerifyMobilePhoneDoneComposer = 91; // PRODUCTION-201611291003-338511768
public final static int RoomUserReceivedHandItemComposer = 354; // PRODUCTION-201611291003-338511768
public final static int HanditemBlockStateComposer = 5105;
public final static int MutedWhisperComposer = 826; // PRODUCTION-201611291003-338511768
public final static int UnknownHintComposer = 1787; // PRODUCTION-201611291003-338511768
public final static int BullyReportClosedComposer = 2674; // PRODUCTION-201611291003-338511768
@@ -19,7 +19,13 @@ public class AddFloorItemComposer extends MessageComposer {
protected ServerMessage composeInternal() {
this.response.init(Outgoing.AddFloorItemComposer);
this.item.serializeFloorData(this.response);
this.response.appendInt(this.item instanceof InteractionGift ? ((((InteractionGift) this.item).getColorId() * 1000) + ((InteractionGift) this.item).getRibbonId()) : (this.item instanceof InteractionMusicDisc ? ((InteractionMusicDisc) this.item).getSongId() : 1));
this.response.appendInt(
this.item instanceof InteractionGift
? ((((InteractionGift) this.item).getColorId() * 1000) + ((InteractionGift) this.item).getRibbonId())
: (this.item instanceof InteractionMusicDisc
? ((InteractionMusicDisc) this.item).getSongId()
: (this.item instanceof InteractionStackWalkHelper ? 2147483001 : 1))
);
this.item.serializeExtradata(this.response);
this.response.appendInt(-1);
this.response.appendInt(this.item instanceof InteractionTeleport || this.item instanceof InteractionSwitch || this.item instanceof InteractionSwitchRemoteControl || this.item instanceof InteractionVendingMachine || this.item instanceof InteractionInformationTerminal || this.item instanceof InteractionPostIt|| this.item instanceof InteractionPuzzleBox ? 2 : this.item.isUsable() ? 1 : 0);
@@ -0,0 +1,30 @@
package com.eu.habbo.messages.outgoing.rooms.items;
import com.eu.habbo.habbohotel.rooms.RoomAreaHideSupport;
import com.eu.habbo.habbohotel.users.HabboItem;
import com.eu.habbo.messages.ServerMessage;
import com.eu.habbo.messages.outgoing.MessageComposer;
import com.eu.habbo.messages.outgoing.Outgoing;
public class AreaHideComposer extends MessageComposer {
private final HabboItem item;
public AreaHideComposer(HabboItem item) {
this.item = item;
}
@Override
protected ServerMessage composeInternal() {
this.response.init(Outgoing.AreaHideComposer);
this.response.appendInt(this.item.getId());
this.response.appendBoolean(RoomAreaHideSupport.isControllerActive(this.item));
this.response.appendInt(RoomAreaHideSupport.getRootX(this.item));
this.response.appendInt(RoomAreaHideSupport.getRootY(this.item));
this.response.appendInt(RoomAreaHideSupport.getWidth(this.item));
this.response.appendInt(RoomAreaHideSupport.getLength(this.item));
this.response.appendBoolean(RoomAreaHideSupport.isInverted(this.item));
this.response.appendBoolean(RoomAreaHideSupport.includesWallItems(this.item));
this.response.appendBoolean(RoomAreaHideSupport.isInvisibilityEnabled(this.item));
return this.response;
}
}
@@ -0,0 +1,34 @@
package com.eu.habbo.messages.outgoing.rooms.items;
import com.eu.habbo.habbohotel.rooms.Room;
import com.eu.habbo.habbohotel.rooms.RoomConfInvisSupport;
import com.eu.habbo.messages.ServerMessage;
import com.eu.habbo.messages.outgoing.MessageComposer;
import com.eu.habbo.messages.outgoing.Outgoing;
import gnu.trove.list.array.TIntArrayList;
public class ConfInvisStateComposer extends MessageComposer {
private final int roomId;
private final boolean active;
private final TIntArrayList hiddenItemIds;
public ConfInvisStateComposer(Room room) {
this.roomId = (room != null) ? room.getId() : 0;
this.active = RoomConfInvisSupport.hasActiveController(room);
this.hiddenItemIds = RoomConfInvisSupport.collectHiddenFloorItemIds(room);
}
@Override
protected ServerMessage composeInternal() {
this.response.init(Outgoing.ConfInvisStateComposer);
this.response.appendInt(this.roomId);
this.response.appendBoolean(this.active);
this.response.appendInt(this.hiddenItemIds.size());
for (int i = 0; i < this.hiddenItemIds.size(); i++) {
this.response.appendInt(this.hiddenItemIds.get(i));
}
return this.response;
}
}
@@ -2,6 +2,7 @@ package com.eu.habbo.messages.outgoing.rooms.items;
import com.eu.habbo.habbohotel.items.interactions.InteractionGift;
import com.eu.habbo.habbohotel.items.interactions.InteractionMusicDisc;
import com.eu.habbo.habbohotel.items.interactions.InteractionStackWalkHelper;
import com.eu.habbo.habbohotel.users.HabboItem;
import com.eu.habbo.messages.ServerMessage;
import com.eu.habbo.messages.outgoing.MessageComposer;
@@ -18,7 +19,13 @@ public class FloorItemUpdateComposer extends MessageComposer {
protected ServerMessage composeInternal() {
this.response.init(Outgoing.FloorItemUpdateComposer);
this.item.serializeFloorData(this.response);
this.response.appendInt(this.item instanceof InteractionGift ? ((((InteractionGift) this.item).getColorId() * 1000) + ((InteractionGift) this.item).getRibbonId()) : (this.item instanceof InteractionMusicDisc ? ((InteractionMusicDisc) this.item).getSongId() : item.isUsable() ? 0 : 0));
this.response.appendInt(
this.item instanceof InteractionGift
? ((((InteractionGift) this.item).getColorId() * 1000) + ((InteractionGift) this.item).getRibbonId())
: (this.item instanceof InteractionMusicDisc
? ((InteractionMusicDisc) this.item).getSongId()
: (this.item instanceof InteractionStackWalkHelper ? 2147483001 : 0))
);
this.item.serializeExtradata(this.response);
this.response.appendInt(-1);
this.response.appendInt(0);
@@ -0,0 +1,25 @@
package com.eu.habbo.messages.outgoing.rooms.items;
import com.eu.habbo.habbohotel.rooms.Room;
import com.eu.habbo.habbohotel.rooms.RoomHanditemBlockSupport;
import com.eu.habbo.messages.ServerMessage;
import com.eu.habbo.messages.outgoing.MessageComposer;
import com.eu.habbo.messages.outgoing.Outgoing;
public class HanditemBlockStateComposer extends MessageComposer {
private final int roomId;
private final boolean blocked;
public HanditemBlockStateComposer(Room room) {
this.roomId = (room != null) ? room.getId() : 0;
this.blocked = RoomHanditemBlockSupport.isHanditemBlocked(room);
}
@Override
protected ServerMessage composeInternal() {
this.response.init(Outgoing.HanditemBlockStateComposer);
this.response.appendInt(this.roomId);
this.response.appendBoolean(this.blocked);
return this.response;
}
}
@@ -41,7 +41,13 @@ public class RoomFloorItemsComposer extends MessageComposer {
for (HabboItem item : this.items) {
item.serializeFloorData(this.response);
this.response.appendInt(item instanceof InteractionGift ? ((((InteractionGift) item).getColorId() * 1000) + ((InteractionGift) item).getRibbonId()) : (item instanceof InteractionMusicDisc ? ((InteractionMusicDisc) item).getSongId() : 1));
this.response.appendInt(
item instanceof InteractionGift
? ((((InteractionGift) item).getColorId() * 1000) + ((InteractionGift) item).getRibbonId())
: (item instanceof InteractionMusicDisc
? ((InteractionMusicDisc) item).getSongId()
: (item instanceof InteractionStackWalkHelper ? 2147483001 : 1))
);
item.serializeExtradata(this.response);
this.response.appendInt(-1);
this.response.appendInt(item instanceof InteractionTeleport || item instanceof InteractionSwitch || item instanceof InteractionSwitchRemoteControl || item instanceof InteractionVendingMachine || item instanceof InteractionInformationTerminal || item instanceof InteractionPostIt || item instanceof InteractionPuzzleBox ? 2 : item.isUsable() ? 1 : 0);
@@ -6,6 +6,7 @@ import com.eu.habbo.habbohotel.items.interactions.InteractionRoller;
import com.eu.habbo.habbohotel.pets.Pet;
import com.eu.habbo.habbohotel.pets.RideablePet;
import com.eu.habbo.habbohotel.rooms.Room;
import com.eu.habbo.habbohotel.rooms.RoomQueueSpeedControlSupport;
import com.eu.habbo.habbohotel.rooms.RoomTile;
import com.eu.habbo.habbohotel.rooms.RoomUnit;
import com.eu.habbo.habbohotel.rooms.RoomUnitType;
@@ -157,7 +158,7 @@ public class RoomUnitOnRollerComposer extends MessageComposer {
}
}
}
}, this.room.getRollerSpeed() == 0 ? 250 : InteractionRoller.DELAY);
}, RoomQueueSpeedControlSupport.getEffectiveRollerIntervalMs(this.room));
/*
RoomTile rollerTile = room.getLayout().getTile(this.roller.getX(), this.roller.getY());
Emulator.getThreading().run(() -> {
@@ -177,7 +178,7 @@ public class RoomUnitOnRollerComposer extends MessageComposer {
}
}
}
}, this.room.getRollerSpeed() == 0 ? 250 : InteractionRoller.DELAY);
}, RoomQueueSpeedControlSupport.getEffectiveRollerIntervalMs(this.room));
*/
} else {
this.roomUnit.setLocation(this.newLocation);
@@ -1,6 +1,8 @@
package com.eu.habbo.threading.runnables;
import com.eu.habbo.habbohotel.users.Habbo;
import com.eu.habbo.habbohotel.rooms.Room;
import com.eu.habbo.habbohotel.rooms.RoomHanditemBlockSupport;
import com.eu.habbo.messages.outgoing.rooms.users.RoomUserHandItemComposer;
import com.eu.habbo.messages.outgoing.rooms.users.RoomUserReceivedHandItemComposer;
@@ -21,6 +23,12 @@ public class HabboGiveHandItemToHabbo implements Runnable {
if (this.from.getHabboInfo().getCurrentRoom() != this.target.getHabboInfo().getCurrentRoom())
return;
Room room = this.from.getHabboInfo().getCurrentRoom();
if (RoomHanditemBlockSupport.isHanditemBlocked(room)) {
return;
}
int itemId = this.from.getRoomUnit().getHandItem();
if (itemId > 0) {