diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMoveRotateUser.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMoveRotateUser.java index 6be0ff53..50e9b916 100644 --- a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMoveRotateUser.java +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectMoveRotateUser.java @@ -15,6 +15,7 @@ import com.eu.habbo.habbohotel.rooms.RoomUserRotation; import com.eu.habbo.habbohotel.wired.WiredEffectType; import com.eu.habbo.habbohotel.wired.core.WiredContext; import com.eu.habbo.habbohotel.wired.core.WiredManager; +import com.eu.habbo.habbohotel.wired.core.WiredMovementPhysics; import com.eu.habbo.habbohotel.wired.core.WiredMoveCarryHelper; import com.eu.habbo.habbohotel.wired.core.WiredSourceUtil; import com.eu.habbo.habbohotel.wired.core.WiredUserMovementHelper; @@ -53,6 +54,7 @@ public class WiredEffectMoveRotateUser extends InteractionWiredEffect { @Override public void execute(WiredContext ctx) { Room room = ctx.room(); + WiredMovementPhysics movementPhysics = WiredMoveCarryHelper.getUserMovementPhysics(room, this, ctx); for (RoomUnit roomUnit : WiredSourceUtil.resolveUsers(ctx, this.userSource)) { if (roomUnit == null || roomUnit.getRoom() != room) { @@ -63,7 +65,7 @@ public class WiredEffectMoveRotateUser extends InteractionWiredEffect { RoomUserRotation targetBodyRotation = hasRotation ? this.getTargetRotation(roomUnit) : roomUnit.getBodyRotation(); RoomUserRotation targetHeadRotation = hasRotation ? targetBodyRotation : roomUnit.getHeadRotation(); RoomTile targetTile = (this.movementDirection >= 0) ? this.getTargetTile(room, roomUnit, this.movementDirection) : null; - boolean canMove = this.canMoveTo(room, roomUnit, targetTile); + boolean canMove = this.canMoveTo(room, roomUnit, targetTile, movementPhysics); boolean noAnimation = WiredMoveCarryHelper.hasNoAnimationExtra(room, this); int animationDuration = noAnimation ? 0 : WiredMoveCarryHelper.getAnimationDuration(room, this, WiredUserMovementHelper.DEFAULT_ANIMATION_DURATION); int activeWindowMs = this.resolveActiveWindow(canMove, hasRotation, noAnimation, animationDuration); @@ -72,7 +74,7 @@ public class WiredEffectMoveRotateUser extends InteractionWiredEffect { double targetZ = targetTile.getStackHeight() + ((targetTile.state == RoomTileState.SIT) ? -0.5 : 0); this.markActive(roomUnit, activeWindowMs); if (!WiredUserMovementHelper.moveUser(room, roomUnit, targetTile, targetZ, targetBodyRotation, targetHeadRotation, - animationDuration, noAnimation)) { + animationDuration, noAnimation, movementPhysics)) { if (hasRotation) { WiredUserMovementHelper.updateUserDirection(room, roomUnit, targetBodyRotation, targetHeadRotation); } @@ -266,22 +268,8 @@ public class WiredEffectMoveRotateUser extends InteractionWiredEffect { return room.getLayout().getTile((short) (currentTile.x + deltaX), (short) (currentTile.y + deltaY)); } - private boolean canMoveTo(Room room, RoomUnit roomUnit, RoomTile targetTile) { - if (targetTile == null || targetTile.state == RoomTileState.INVALID || targetTile.state == RoomTileState.BLOCKED) { - return false; - } - - if (!room.tileWalkable(targetTile)) { - return false; - } - - for (RoomUnit unit : room.getRoomUnitsAt(targetTile)) { - if (unit != null && unit != roomUnit) { - return false; - } - } - - return true; + private boolean canMoveTo(Room room, RoomUnit roomUnit, RoomTile targetTile, WiredMovementPhysics movementPhysics) { + return WiredUserMovementHelper.canMoveTo(room, roomUnit, targetTile, movementPhysics); } private void markActive(RoomUnit roomUnit, int durationMs) { diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectUserToFurni.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectUserToFurni.java index 2d2491d5..69960024 100644 --- a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectUserToFurni.java +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/effects/WiredEffectUserToFurni.java @@ -14,6 +14,7 @@ import com.eu.habbo.habbohotel.users.HabboItem; import com.eu.habbo.habbohotel.wired.WiredEffectType; import com.eu.habbo.habbohotel.wired.core.WiredContext; import com.eu.habbo.habbohotel.wired.core.WiredManager; +import com.eu.habbo.habbohotel.wired.core.WiredMovementPhysics; import com.eu.habbo.habbohotel.wired.core.WiredMoveCarryHelper; import com.eu.habbo.habbohotel.wired.core.WiredSourceUtil; import com.eu.habbo.habbohotel.wired.core.WiredUserMovementHelper; @@ -47,6 +48,7 @@ public class WiredEffectUserToFurni extends WiredEffectUserFurniBase { public void execute(WiredContext ctx) { Room room = ctx.room(); HabboItem item = this.resolveLastItem(ctx); + WiredMovementPhysics movementPhysics = WiredMoveCarryHelper.getUserMovementPhysics(room, this, ctx); if (room == null || item == null) { return; @@ -58,7 +60,7 @@ public class WiredEffectUserToFurni extends WiredEffectUserFurniBase { } for (Habbo habbo : this.resolveHabbos(room, ctx)) { - this.moveHabboSmooth(room, habbo, item, targetTile); + this.moveHabboSmooth(room, habbo, item, targetTile, movementPhysics); } } @@ -227,7 +229,7 @@ public class WiredEffectUserToFurni extends WiredEffectUserFurniBase { return true; } - private void moveHabboSmooth(Room room, Habbo habbo, HabboItem item, RoomTile targetTile) { + private void moveHabboSmooth(Room room, Habbo habbo, HabboItem item, RoomTile targetTile, WiredMovementPhysics movementPhysics) { if (room == null || habbo == null || item == null || targetTile == null || habbo.getRoomUnit() == null) { return; } @@ -245,7 +247,7 @@ public class WiredEffectUserToFurni extends WiredEffectUserFurniBase { double newZ = item.getZ() + Item.getCurrentHeight(item); int animationDuration = noAnimation ? 0 : WiredMoveCarryHelper.getAnimationDuration(room, this, WiredUserMovementHelper.DEFAULT_ANIMATION_DURATION); if (!WiredUserMovementHelper.moveUser(room, roomUnit, targetTile, newZ, - roomUnit.getBodyRotation(), roomUnit.getHeadRotation(), animationDuration, noAnimation)) { + roomUnit.getBodyRotation(), roomUnit.getHeadRotation(), animationDuration, noAnimation, movementPhysics)) { return; } diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/extra/WiredExtraVariableTextConnector.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/extra/WiredExtraVariableTextConnector.java index eb419c03..388f30a4 100644 --- a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/extra/WiredExtraVariableTextConnector.java +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/wired/extra/WiredExtraVariableTextConnector.java @@ -1,11 +1,13 @@ package com.eu.habbo.habbohotel.items.interactions.wired.extra; +import com.eu.habbo.Emulator; import com.eu.habbo.habbohotel.gameclients.GameClient; import com.eu.habbo.habbohotel.items.Item; import com.eu.habbo.habbohotel.items.interactions.InteractionWiredExtra; import com.eu.habbo.habbohotel.items.interactions.wired.WiredSettings; import com.eu.habbo.habbohotel.rooms.Room; import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.wired.core.WiredContextVariableSupport; import com.eu.habbo.habbohotel.wired.core.WiredManager; import com.eu.habbo.messages.ServerMessage; @@ -38,6 +40,12 @@ public class WiredExtraVariableTextConnector extends InteractionWiredExtra { @Override public boolean saveData(WiredSettings settings, GameClient gameClient) { this.setMappingsText(settings.getStringParam()); + + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); + if (room != null) { + WiredContextVariableSupport.broadcastDefinitions(room); + } + return true; } diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomItemManager.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomItemManager.java index a52b9c3e..a95a5cd7 100644 --- a/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomItemManager.java +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/rooms/RoomItemManager.java @@ -21,6 +21,7 @@ import com.eu.habbo.habbohotel.items.interactions.wired.extra.WiredExtraRoomVari import com.eu.habbo.habbohotel.items.interactions.wired.extra.WiredExtraUserVariable; import com.eu.habbo.habbohotel.items.interactions.wired.extra.WiredExtraVariableEcho; import com.eu.habbo.habbohotel.items.interactions.wired.extra.WiredExtraVariableReference; +import com.eu.habbo.habbohotel.items.interactions.wired.extra.WiredExtraVariableTextConnector; import com.eu.habbo.habbohotel.items.interactions.wired.extra.WiredExtraContextVariable; import com.eu.habbo.habbohotel.wired.core.WiredContextVariableSupport; import com.eu.habbo.habbohotel.items.interactions.wired.triggers.WiredTriggerReceiveSignal; @@ -807,6 +808,7 @@ public class RoomItemManager { isWiredItem = true; } else if (item instanceof InteractionWiredExtra) { boolean removedContextDefinition = false; + boolean removedVariableTextConnector = false; if (item instanceof WiredExtraUserVariable) { this.room.getUserVariableManager().removeDefinition(item.getId()); } else if (item instanceof WiredExtraFurniVariable) { @@ -815,6 +817,8 @@ public class RoomItemManager { this.room.getRoomVariableManager().removeDefinition(item.getId()); } else if (item instanceof WiredExtraContextVariable) { removedContextDefinition = true; + } else if (item instanceof WiredExtraVariableTextConnector) { + removedVariableTextConnector = true; } else if (item instanceof WiredExtraVariableReference) { if (((WiredExtraVariableReference) item).isRoomReference()) { this.room.getRoomVariableManager().removeDefinition(item.getId()); @@ -833,7 +837,7 @@ public class RoomItemManager { } } specialTypes.removeExtra((InteractionWiredExtra) item); - if (removedContextDefinition) { + if (removedContextDefinition || removedVariableTextConnector) { WiredContextVariableSupport.broadcastDefinitions(this.room); } isWiredItem = true; diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/core/WiredMoveCarryHelper.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/core/WiredMoveCarryHelper.java index 49e14b04..5647a45e 100644 --- a/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/core/WiredMoveCarryHelper.java +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/core/WiredMoveCarryHelper.java @@ -404,6 +404,14 @@ public final class WiredMoveCarryHelper { return (extra != null) ? extra.getDurationMs() : fallbackDuration; } + public static WiredMovementPhysics getUserMovementPhysics(Room room, HabboItem stackItem, WiredContext ctx) { + if (room == null || stackItem == null) { + return WiredMovementPhysics.NONE; + } + + return getMovementPhysics(room, stackItem, null, ctx); + } + public static int resolveMoveStepElapsed(RoomUnit roomUnit) { if (roomUnit == null) { return 0; diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/core/WiredUserMovementHelper.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/core/WiredUserMovementHelper.java index 9777db22..2ead572e 100644 --- a/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/core/WiredUserMovementHelper.java +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/wired/core/WiredUserMovementHelper.java @@ -19,6 +19,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; +import java.util.LinkedList; import java.util.List; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -36,20 +37,26 @@ public final class WiredUserMovementHelper { public static boolean moveUser(Room room, RoomUnit roomUnit, RoomTile targetTile, double targetZ, int duration) { return moveUser(room, roomUnit, targetTile, targetZ, roomUnit == null ? null : roomUnit.getBodyRotation(), - roomUnit == null ? null : roomUnit.getHeadRotation(), duration, false); + roomUnit == null ? null : roomUnit.getHeadRotation(), duration, false, WiredMovementPhysics.NONE); } public static boolean moveUser(Room room, RoomUnit roomUnit, RoomTile targetTile, double targetZ, RoomUserRotation bodyRotation, RoomUserRotation headRotation, int duration) { - return moveUser(room, roomUnit, targetTile, targetZ, bodyRotation, headRotation, duration, false); + return moveUser(room, roomUnit, targetTile, targetZ, bodyRotation, headRotation, duration, false, WiredMovementPhysics.NONE); } public static boolean moveUser(Room room, RoomUnit roomUnit, RoomTile targetTile, double targetZ, RoomUserRotation bodyRotation, RoomUserRotation headRotation, int duration, boolean noAnimation) { + return moveUser(room, roomUnit, targetTile, targetZ, bodyRotation, headRotation, duration, noAnimation, WiredMovementPhysics.NONE); + } + + public static boolean moveUser(Room room, RoomUnit roomUnit, RoomTile targetTile, double targetZ, RoomUserRotation bodyRotation, RoomUserRotation headRotation, int duration, boolean noAnimation, WiredMovementPhysics movementPhysics) { if (room == null || roomUnit == null || targetTile == null || room.getLayout() == null) { return false; } RoomTile oldLocation = roomUnit.getCurrentLocation(); - if (oldLocation == null || hasBlockingUnits(room, roomUnit, targetTile)) { + WiredMovementPhysics resolvedMovementPhysics = movementPhysics == null ? WiredMovementPhysics.NONE : movementPhysics; + + if (oldLocation == null || !canMoveTo(room, roomUnit, targetTile, resolvedMovementPhysics)) { return false; } @@ -66,13 +73,12 @@ public final class WiredUserMovementHelper { } runWithSuppressedStatusUpdates(Collections.singletonList(roomUnit), () -> { - roomUnit.setPreviousLocation(oldLocation); - roomUnit.setCurrentLocation(targetTile); roomUnit.removeStatus(RoomUnitStatus.MOVE); roomUnit.setZ(targetZ); + roomUnit.setLocation(targetTile); + roomUnit.setPath(new LinkedList<>()); roomUnit.setBodyRotation(resolvedBodyRotation); roomUnit.setHeadRotation(resolvedHeadRotation); - roomUnit.stopWalking(); roomUnit.resetIdleTimer(); if (habbo != null) { @@ -99,10 +105,8 @@ public final class WiredUserMovementHelper { suppressStatusComposer(roomUnit, animationDuration); room.sendComposer(new WiredMovementsComposer(movements).compose()); - roomUnit.setPreviousLocation(targetTile); - roomUnit.setPreviousLocationZ(roomUnit.getZ()); - scheduleTileCallbacks(room, roomUnit, oldLocation, targetTile, oldTopItem, newTopItem, animationDuration); + scheduleFinalStatusSync(room, roomUnit, targetTile, animationDuration); schedulePostureSync(room, roomUnit, targetTile, animationDuration); return true; } @@ -161,7 +165,32 @@ public final class WiredUserMovementHelper { SUPPRESSED_STATUS_COMPOSER_UNTIL.remove(roomUnit.getId()); } - private static boolean hasBlockingUnits(Room room, RoomUnit roomUnit, RoomTile targetTile) { + public static boolean canMoveTo(Room room, RoomUnit roomUnit, RoomTile targetTile, WiredMovementPhysics movementPhysics) { + if (room == null || roomUnit == null || targetTile == null) { + return false; + } + + WiredMovementPhysics resolvedMovementPhysics = movementPhysics == null ? WiredMovementPhysics.NONE : movementPhysics; + + if (targetTile.state == null || targetTile.state == com.eu.habbo.habbohotel.rooms.RoomTileState.INVALID) { + return false; + } + + if (targetTile.state == com.eu.habbo.habbohotel.rooms.RoomTileState.BLOCKED + && !canBypassBlockedTile(room, targetTile, resolvedMovementPhysics)) { + return false; + } + + if (!room.getLayout().tileWalkable(targetTile.x, targetTile.y) + && !room.canSitOrLayAt(targetTile.x, targetTile.y) + && !canBypassBlockedTile(room, targetTile, resolvedMovementPhysics)) { + return false; + } + + return !hasBlockingUnits(room, roomUnit, targetTile, resolvedMovementPhysics); + } + + private static boolean hasBlockingUnits(Room room, RoomUnit roomUnit, RoomTile targetTile, WiredMovementPhysics movementPhysics) { Collection units = room.getRoomUnitsAt(targetTile); if (units == null || units.isEmpty()) { @@ -169,7 +198,9 @@ public final class WiredUserMovementHelper { } for (RoomUnit targetUnit : units) { - if (targetUnit != null && targetUnit != roomUnit) { + if (targetUnit != null + && targetUnit != roomUnit + && !movementPhysics.shouldIgnoreUser(targetUnit)) { return true; } } @@ -177,15 +208,50 @@ public final class WiredUserMovementHelper { return false; } + private static boolean canBypassBlockedTile(Room room, RoomTile targetTile, WiredMovementPhysics movementPhysics) { + if (room == null || targetTile == null || movementPhysics == null || !movementPhysics.isActive()) { + return false; + } + + Collection items = room.getItemsAt(targetTile); + if (items == null || items.isEmpty()) { + return false; + } + + boolean hasIgnoredFurni = false; + + for (HabboItem item : items) { + if (item == null) { + continue; + } + + if (movementPhysics.isBlockingFurni(item)) { + return false; + } + + if (movementPhysics.shouldIgnoreFurni(item)) { + hasIgnoredFurni = true; + continue; + } + + if (!item.isWalkable() + && !item.getBaseItem().allowSit() + && !item.getBaseItem().allowLay()) { + return false; + } + } + + return hasIgnoredFurni; + } + private static boolean moveUserInstant(Room room, RoomUnit roomUnit, RoomTile targetTile, double targetZ, RoomUserRotation bodyRotation, RoomUserRotation headRotation, RoomTile oldLocation, HabboItem oldTopItem, HabboItem newTopItem, Habbo habbo) { runWithSuppressedStatusUpdates(Collections.singletonList(roomUnit), () -> { - roomUnit.setPreviousLocation(oldLocation); - roomUnit.setCurrentLocation(targetTile); roomUnit.removeStatus(RoomUnitStatus.MOVE); roomUnit.setZ(targetZ); + roomUnit.setLocation(targetTile); + roomUnit.setPath(new LinkedList<>()); roomUnit.setBodyRotation(bodyRotation); roomUnit.setHeadRotation(headRotation); - roomUnit.stopWalking(); roomUnit.resetIdleTimer(); if (habbo != null) { @@ -193,13 +259,12 @@ public final class WiredUserMovementHelper { movedHabbos.add(habbo); room.updateHabbosAt(targetTile.x, targetTile.y, movedHabbos); } - - roomUnit.setPreviousLocation(targetTile); - roomUnit.setPreviousLocationZ(roomUnit.getZ()); roomUnit.statusUpdate(false); }); processTileCallbacks(room, roomUnit, oldLocation, targetTile, oldTopItem, newTopItem); + roomUnit.setPreviousLocation(roomUnit.getCurrentLocation()); + roomUnit.setPreviousLocationZ(roomUnit.getZ()); room.sendComposer(new RoomUserStatusComposer(roomUnit).compose()); return true; } @@ -258,6 +323,29 @@ public final class WiredUserMovementHelper { }, delay + STATUS_SUPPRESSION_GRACE_MS + 25); } + private static void scheduleFinalStatusSync(Room room, RoomUnit roomUnit, RoomTile targetTile, int delay) { + if (room == null || roomUnit == null || targetTile == null) { + return; + } + + Emulator.getThreading().run(() -> { + if (room == null || !room.isLoaded() || roomUnit == null || roomUnit.getCurrentLocation() == null) { + return; + } + + if (roomUnit.isWalking() + || roomUnit.getCurrentLocation().x != targetTile.x + || roomUnit.getCurrentLocation().y != targetTile.y) { + return; + } + + clearStatusComposerSuppression(roomUnit); + roomUnit.setPreviousLocation(roomUnit.getCurrentLocation()); + roomUnit.setPreviousLocationZ(roomUnit.getZ()); + room.sendComposer(new RoomUserStatusComposer(roomUnit).compose()); + }, Math.max(delay, 1) + 25); + } + private static void suppressStatusComposer(RoomUnit roomUnit, int duration) { if (roomUnit == null) { return; diff --git a/Emulator/src/main/java/com/eu/habbo/messages/PacketManager.java b/Emulator/src/main/java/com/eu/habbo/messages/PacketManager.java index 72fe9403..c3fe35d4 100644 --- a/Emulator/src/main/java/com/eu/habbo/messages/PacketManager.java +++ b/Emulator/src/main/java/com/eu/habbo/messages/PacketManager.java @@ -70,6 +70,7 @@ import com.eu.habbo.messages.incoming.wired.WiredEffectSaveDataEvent; import com.eu.habbo.messages.incoming.wired.WiredMonitorRequestEvent; import com.eu.habbo.messages.incoming.wired.WiredRoomSettingsRequestEvent; import com.eu.habbo.messages.incoming.wired.WiredRoomSettingsSaveEvent; +import com.eu.habbo.messages.incoming.wired.WiredUserInspectMoveEvent; import com.eu.habbo.messages.incoming.wired.WiredUserVariableManageEvent; import com.eu.habbo.messages.incoming.wired.WiredUserVariableUpdateEvent; import com.eu.habbo.messages.incoming.wired.WiredUserVariablesRequestEvent; @@ -627,6 +628,7 @@ public class PacketManager { this.registerHandler(Incoming.WiredUserVariablesRequestEvent, WiredUserVariablesRequestEvent.class); this.registerHandler(Incoming.WiredUserVariableUpdateEvent, WiredUserVariableUpdateEvent.class); this.registerHandler(Incoming.WiredUserVariableManageEvent, WiredUserVariableManageEvent.class); + this.registerHandler(Incoming.WiredUserInspectMoveEvent, WiredUserInspectMoveEvent.class); } void registerUnknown() throws Exception { diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/Incoming.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/Incoming.java index 4f8554cf..2c1aad0a 100644 --- a/Emulator/src/main/java/com/eu/habbo/messages/incoming/Incoming.java +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/Incoming.java @@ -415,6 +415,7 @@ public class Incoming { public static final int WiredUserVariablesRequestEvent = 10024; public static final int WiredUserVariableUpdateEvent = 10025; public static final int WiredUserVariableManageEvent = 10026; + public static final int WiredUserInspectMoveEvent = 10027; public static final int RequestInventoryPetDelete = 10030; public static final int RequestInventoryBadgeDelete = 10031; diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserWalkEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserWalkEvent.java index e54fc6e7..26f499c6 100644 --- a/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserWalkEvent.java +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/rooms/users/RoomUserWalkEvent.java @@ -120,8 +120,19 @@ public class RoomUserWalkEvent extends MessageHandler { roomUnit.getMoveBlockingTask().get(); } - if (WiredUserMovementHelper.shouldSuppressStatusComposer(roomUnit)) { + boolean needsLocationResync = + roomUnit.getCurrentLocation() != null + && (roomUnit.getPreviousLocation() == null + || roomUnit.getPreviousLocation().x != roomUnit.getCurrentLocation().x + || roomUnit.getPreviousLocation().y != roomUnit.getCurrentLocation().y + || Math.abs(roomUnit.getPreviousLocationZ() - roomUnit.getZ()) > 0.01D); + + if (WiredUserMovementHelper.shouldSuppressStatusComposer(roomUnit) || needsLocationResync) { WiredUserMovementHelper.clearStatusComposerSuppression(roomUnit); + if (roomUnit.getCurrentLocation() != null) { + roomUnit.setPreviousLocation(roomUnit.getCurrentLocation()); + roomUnit.setPreviousLocationZ(roomUnit.getZ()); + } room.sendComposer(new RoomUserStatusComposer(roomUnit).compose()); } diff --git a/Emulator/src/main/java/com/eu/habbo/messages/incoming/wired/WiredUserInspectMoveEvent.java b/Emulator/src/main/java/com/eu/habbo/messages/incoming/wired/WiredUserInspectMoveEvent.java new file mode 100644 index 00000000..fd159b9e --- /dev/null +++ b/Emulator/src/main/java/com/eu/habbo/messages/incoming/wired/WiredUserInspectMoveEvent.java @@ -0,0 +1,83 @@ +package com.eu.habbo.messages.incoming.wired; + +import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.rooms.RoomTileState; +import com.eu.habbo.habbohotel.rooms.RoomUnit; +import com.eu.habbo.habbohotel.rooms.RoomUserRotation; +import com.eu.habbo.habbohotel.wired.core.WiredUserMovementHelper; +import com.eu.habbo.messages.incoming.MessageHandler; + +public class WiredUserInspectMoveEvent extends MessageHandler { + @Override + public void handle() throws Exception { + Room room = currentRoom(); + + if (room == null) { + return; + } + + if (!room.canModifyWired(this.client.getHabbo())) { + return; + } + + if (this.packet.bytesAvailable() < 16) { + return; + } + + int roomUnitId = this.packet.readInt(); + int x = this.packet.readInt(); + int y = this.packet.readInt(); + int direction = this.packet.readInt(); + + RoomUnit roomUnit = resolveRoomUnit(room, roomUnitId); + + if (roomUnit == null || roomUnit.getCurrentLocation() == null || room.getLayout() == null) { + return; + } + + RoomUserRotation targetRotation = RoomUserRotation.fromValue((((direction % 8) + 8) % 8)); + boolean positionChanged = roomUnit.getX() != x || roomUnit.getY() != y; + boolean directionChanged = roomUnit.getBodyRotation() != targetRotation || roomUnit.getHeadRotation() != targetRotation; + + if (!positionChanged) { + if (directionChanged) { + WiredUserMovementHelper.updateUserDirection(room, roomUnit, targetRotation, targetRotation); + } + + return; + } + + RoomTile targetTile = room.getLayout().getTile((short) x, (short) y); + + if (targetTile == null || targetTile.state == RoomTileState.INVALID || targetTile.state == RoomTileState.BLOCKED) { + return; + } + + double targetZ = targetTile.getStackHeight() + ((targetTile.state == RoomTileState.SIT) ? -0.5 : 0); + + if (!WiredUserMovementHelper.moveUser(room, roomUnit, targetTile, targetZ, targetRotation, targetRotation, WiredUserMovementHelper.DEFAULT_ANIMATION_DURATION, false) + && directionChanged) { + WiredUserMovementHelper.updateUserDirection(room, roomUnit, targetRotation, targetRotation); + } + } + + @Override + public int getRatelimit() { + return 100; + } + + private RoomUnit resolveRoomUnit(Room room, int roomUnitId) { + if (room == null || roomUnitId <= 0) { + return null; + } + + for (RoomUnit roomUnit : room.getRoomUnits()) { + if (roomUnit != null && roomUnit.getId() == roomUnitId) { + return roomUnit; + } + } + + return null; + } +} diff --git a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomDataComposer.java b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomDataComposer.java index 4f6163bc..50770114 100644 --- a/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomDataComposer.java +++ b/Emulator/src/main/java/com/eu/habbo/messages/outgoing/rooms/RoomDataComposer.java @@ -3,6 +3,7 @@ package com.eu.habbo.messages.outgoing.rooms; import com.eu.habbo.Emulator; import com.eu.habbo.habbohotel.guilds.Guild; import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomPromotion; import com.eu.habbo.habbohotel.users.Habbo; import com.eu.habbo.messages.ServerMessage; import com.eu.habbo.messages.outgoing.MessageComposer; @@ -24,6 +25,9 @@ public class RoomDataComposer extends MessageComposer { @Override protected ServerMessage composeInternal() { + final RoomPromotion promotion = this.room.getPromotion(); + final boolean hasPromotion = this.room.isPromoted() && (promotion != null); + this.response.init(Outgoing.RoomDataComposer); this.response.appendBoolean(this.enterRoom); this.response.appendInt(this.room.getId()); @@ -64,7 +68,7 @@ public class RoomDataComposer extends MessageComposer { base = base | 8; } - if (this.room.isPromoted()) { + if (hasPromotion) { base = base | 4; } @@ -87,10 +91,10 @@ public class RoomDataComposer extends MessageComposer { } } - if (this.room.isPromoted()) { - this.response.appendString(this.room.getPromotion().getTitle()); - this.response.appendString(this.room.getPromotion().getDescription()); - this.response.appendInt((this.room.getPromotion().getEndTimestamp() - Emulator.getIntUnixTimestamp()) / 60); + if (hasPromotion) { + this.response.appendString(promotion.getTitle()); + this.response.appendString(promotion.getDescription()); + this.response.appendInt((promotion.getEndTimestamp() - Emulator.getIntUnixTimestamp()) / 60); } this.response.appendBoolean(this.roomForward);