diff --git a/src/main/java/com/eu/habbo/habbohotel/items/ItemManager.java b/src/main/java/com/eu/habbo/habbohotel/items/ItemManager.java index f702d68c..e62b1f0a 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/ItemManager.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/ItemManager.java @@ -161,6 +161,7 @@ public class ItemManager { this.interactionsList.add(new ItemInteraction("viking_cotie", InteractionVikingCotie.class)); this.interactionsList.add(new ItemInteraction("tile_fxprovider_nfs", InteractionTileEffectProvider.class)); this.interactionsList.add(new ItemInteraction("mutearea", InteractionMuteArea.class)); + this.interactionsList.add(new ItemInteraction("buildarea", InteractionBuildArea.class)); this.interactionsList.add(new ItemInteraction("information_terminal", InteractionInformationTerminal.class)); this.interactionsList.add(new ItemInteraction("external_image", InteractionExternalImage.class)); this.interactionsList.add(new ItemInteraction("youtube", InteractionYoutubeTV.class)); diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionBuildArea.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionBuildArea.java new file mode 100644 index 00000000..015ab451 --- /dev/null +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionBuildArea.java @@ -0,0 +1,253 @@ +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.RoomTile; +import com.eu.habbo.habbohotel.rooms.RoomTileState; +import com.eu.habbo.habbohotel.users.Habbo; +import com.eu.habbo.habbohotel.users.HabboInfo; +import com.eu.habbo.habbohotel.users.HabboItem; +import com.eu.habbo.habbohotel.users.HabboManager; +import com.eu.habbo.messages.outgoing.rooms.items.RemoveFloorItemComposer; +import com.eu.habbo.messages.outgoing.rooms.items.RoomFloorItemsComposer; +import gnu.trove.TCollections; +import gnu.trove.map.TIntObjectMap; +import gnu.trove.map.hash.THashMap; +import gnu.trove.map.hash.TIntObjectHashMap; +import gnu.trove.set.hash.THashSet; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; + +public class InteractionBuildArea extends InteractionCustomValues { + public static THashMap defaultValues = new THashMap() { + { + this.put("tilesLeft", "0"); + } + + { + this.put("tilesRight", "0"); + } + + { + this.put("tilesFront", "0"); + } + + { + this.put("tilesBack", "0"); + } + + { + this.put("builders", ""); + } + }; + + private THashSet tiles; + + public InteractionBuildArea(ResultSet set, Item baseItem) throws SQLException { + super(set, baseItem, defaultValues); + tiles = new THashSet<>(); + } + + public InteractionBuildArea(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) { + super(id, userId, item, extradata, limitedStack, limitedSells, defaultValues); + tiles = new THashSet<>(); + } + + @Override + public void onPlace(Room room) { + super.onPlace(room); + this.regenAffectedTiles(room); + } + + @Override + public void onPickUp(Room room) { + super.onPickUp(room); + + ArrayList builderNames = new ArrayList<>(Arrays.asList(this.values.get("builders").split(";"))); + THashSet canBuild = new THashSet<>(); + + for (String builderName : builderNames) { + Habbo builder = Emulator.getGameEnvironment().getHabboManager().getHabbo(builderName); + HabboInfo builderInfo; + if (builder != null) { + builderInfo = builder.getHabboInfo(); + } else { + builderInfo = HabboManager.getOfflineHabboInfo(builderName); + } + if (builderInfo != null) { + canBuild.add(builderInfo.getId()); + } + } + + if (!canBuild.isEmpty()) { + for (RoomTile tile : this.tiles) { + THashSet tileItems = room.getItemsAt(tile); + for (HabboItem tileItem : tileItems) { + if (canBuild.contains(tileItem.getUserId()) && tileItem != this) { + room.pickUpItem(tileItem, null); + } + } + } + } + + this.tiles.clear(); + } + + @Override + public void onMove(Room room, RoomTile oldLocation, RoomTile newLocation) { + super.onMove(room, oldLocation, newLocation); + + ArrayList builderNames = new ArrayList<>(Arrays.asList(this.values.get("builders").split(";"))); + THashSet canBuild = new THashSet<>(); + + for (String builderName : builderNames) { + Habbo builder = Emulator.getGameEnvironment().getHabboManager().getHabbo(builderName); + HabboInfo builderInfo; + if (builder != null) { + builderInfo = builder.getHabboInfo(); + } else { + builderInfo = HabboManager.getOfflineHabboInfo(builderName); + } + if (builderInfo != null) { + canBuild.add(builderInfo.getId()); + } + } + + THashSet oldTiles = this.tiles; + THashSet newTiles = new THashSet<>(); + + int minX = Math.max(0, newLocation.x - Integer.parseInt(this.values.get("tilesBack"))); + int minY = Math.max(0, newLocation.y - Integer.parseInt(this.values.get("tilesRight"))); + int maxX = Math.min(room.getLayout().getMapSizeX(), newLocation.x + Integer.parseInt(this.values.get("tilesFront"))); + int maxY = Math.min(room.getLayout().getMapSizeY(), newLocation.y + Integer.parseInt(this.values.get("tilesLeft"))); + + for (int x = minX; x <= maxX; x++) { + for (int y = minY; y <= maxY; y++) { + RoomTile tile = room.getLayout().getTile((short) x, (short) y); + if (tile != null && tile.state != RoomTileState.INVALID) + newTiles.add(tile); + } + } + + if (!canBuild.isEmpty()) { + for (RoomTile tile : oldTiles) { + THashSet tileItems = room.getItemsAt(tile); + if(newTiles.contains(tile)) continue; + for (HabboItem tileItem : tileItems) { + if (canBuild.contains(tileItem.getUserId()) && tileItem != this) { + room.pickUpItem(tileItem, null); + } + } + } + } + this.regenAffectedTiles(room); + } + + public boolean inSquare(RoomTile location) { + Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()); + + if (room != null && this.tiles.size() == 0) { + regenAffectedTiles(room); + } + + return this.tiles.contains(location); + + } + + private void regenAffectedTiles(Room room) { + int minX = Math.max(0, this.getX() - Integer.parseInt(this.values.get("tilesBack"))); + int minY = Math.max(0, this.getY() - Integer.parseInt(this.values.get("tilesRight"))); + int maxX = Math.min(room.getLayout().getMapSizeX(), this.getX() + Integer.parseInt(this.values.get("tilesFront"))); + int maxY = Math.min(room.getLayout().getMapSizeY(), this.getY() + Integer.parseInt(this.values.get("tilesLeft"))); + + this.tiles.clear(); + + for (int x = minX; x <= maxX; x++) { + for (int y = minY; y <= maxY; y++) { + RoomTile tile = room.getLayout().getTile((short) x, (short) y); + if (tile != null && tile.state != RoomTileState.INVALID) + this.tiles.add(tile); + } + } + } + + @Override + public void onCustomValuesSaved(Room room, GameClient client, THashMap oldValues) { + regenAffectedTiles(room); + ArrayList builderNames = new ArrayList<>(Arrays.asList(this.values.get("builders").split(";"))); + THashSet canBuild = new THashSet<>(); + + for (String builderName : builderNames) { + Habbo builder = Emulator.getGameEnvironment().getHabboManager().getHabbo(builderName); + HabboInfo builderInfo; + if (builder != null) { + builderInfo = builder.getHabboInfo(); + } else { + builderInfo = HabboManager.getOfflineHabboInfo(builderName); + } + if (builderInfo != null) { + canBuild.add(builderInfo.getId()); + } + } + + THashSet oldTiles = new THashSet<>(); + + int minX = Math.max(0, this.getX() - Integer.parseInt(oldValues.get("tilesBack"))); + int minY = Math.max(0, this.getY() - Integer.parseInt(oldValues.get("tilesRight"))); + int maxX = Math.min(room.getLayout().getMapSizeX(), this.getX() + Integer.parseInt(oldValues.get("tilesFront"))); + int maxY = Math.min(room.getLayout().getMapSizeY(), this.getY() + Integer.parseInt(oldValues.get("tilesLeft"))); + + for (int x = minX; x <= maxX; x++) { + for (int y = minY; y <= maxY; y++) { + RoomTile tile = room.getLayout().getTile((short) x, (short) y); + if (tile != null && tile.state != RoomTileState.INVALID && !this.tiles.contains(tile)) + oldTiles.add(tile); + } + } + if (!canBuild.isEmpty()) { + for (RoomTile tile : oldTiles) { + THashSet tileItems = room.getItemsAt(tile); + for (HabboItem tileItem : tileItems) { + if (canBuild.contains(tileItem.getUserId()) && tileItem != this) { + room.pickUpItem(tileItem, null); + } + } + } + } + + // show the effect + Item effectItem = Emulator.getGameEnvironment().getItemManager().getItem("mutearea_sign2"); + + if(effectItem != null) { + TIntObjectMap ownerNames = TCollections.synchronizedMap(new TIntObjectHashMap<>(0)); + ownerNames.put(-1, "System"); + THashSet items = new THashSet<>(); + + int id = 0; + for(RoomTile tile : this.tiles) { + id--; + HabboItem item = new InteractionDefault(id, -1, effectItem, "1", 0, 0); + item.setX(tile.x); + item.setY(tile.y); + item.setZ(tile.relativeHeight()); + items.add(item); + } + + client.sendResponse(new RoomFloorItemsComposer(ownerNames, items)); + Emulator.getThreading().run(() -> { + for(HabboItem item : items) { + client.sendResponse(new RemoveFloorItemComposer(item, true)); + } + }, 3000); + } + } + + public boolean isBuilder(String Username){ + return Arrays.asList(this.values.get("builders").split(";")).contains(Username); + } +} diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionCustomValues.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionCustomValues.java index 9ef005bc..5a275c28 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionCustomValues.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionCustomValues.java @@ -80,7 +80,7 @@ public abstract class InteractionCustomValues extends HabboItem { super.serializeExtradata(serverMessage); } - public void onCustomValuesSaved(Room room, GameClient client) { + public void onCustomValuesSaved(Room room, GameClient client, THashMap oldValues) { } } diff --git a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMuteArea.java b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMuteArea.java index 29a7c0ac..beed1131 100644 --- a/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMuteArea.java +++ b/src/main/java/com/eu/habbo/habbohotel/items/interactions/InteractionMuteArea.java @@ -17,7 +17,6 @@ import gnu.trove.map.hash.THashMap; import gnu.trove.map.hash.TIntObjectHashMap; import gnu.trove.set.hash.THashSet; -import java.awt.*; import java.sql.ResultSet; import java.sql.SQLException; @@ -125,8 +124,8 @@ public class InteractionMuteArea extends InteractionCustomValues { } @Override - public void onCustomValuesSaved(Room room, GameClient client) { - super.onCustomValuesSaved(room, client); + public void onCustomValuesSaved(Room room, GameClient client, THashMap oldValues) { + super.onCustomValuesSaved(room, client, oldValues); this.regenAffectedTiles(room); diff --git a/src/main/java/com/eu/habbo/habbohotel/rooms/Room.java b/src/main/java/com/eu/habbo/habbohotel/rooms/Room.java index af82a1ae..09c54558 100644 --- a/src/main/java/com/eu/habbo/habbohotel/rooms/Room.java +++ b/src/main/java/com/eu/habbo/habbohotel/rooms/Room.java @@ -2407,6 +2407,8 @@ public class Room implements Comparable, ISerialize, Runnable { this.roomSpecialTypes.addUndefined(item); } else if (item instanceof InteractionMuteArea) { this.roomSpecialTypes.addUndefined(item); + } else if (item instanceof InteractionBuildArea) { + this.roomSpecialTypes.addUndefined(item); } else if (item instanceof InteractionTagPole) { this.roomSpecialTypes.addUndefined(item); } else if (item instanceof InteractionTagField) { @@ -4487,6 +4489,12 @@ public class Room implements Comparable, ISerialize, Runnable { } } + for (HabboItem area : this.getRoomSpecialTypes().getItemsOfType(InteractionBuildArea.class)) { + if (((InteractionBuildArea) area).inSquare(tile) && ((InteractionBuildArea) area).isBuilder(habbo.getHabboInfo().getUsername())) { + return FurnitureMovementError.NONE; + } + } + return FurnitureMovementError.NO_RIGHTS; } diff --git a/src/main/java/com/eu/habbo/messages/incoming/rooms/items/AdvertisingSaveEvent.java b/src/main/java/com/eu/habbo/messages/incoming/rooms/items/AdvertisingSaveEvent.java index d705f8ff..b25f3792 100644 --- a/src/main/java/com/eu/habbo/messages/incoming/rooms/items/AdvertisingSaveEvent.java +++ b/src/main/java/com/eu/habbo/messages/incoming/rooms/items/AdvertisingSaveEvent.java @@ -6,6 +6,9 @@ import com.eu.habbo.habbohotel.items.interactions.InteractionRoomAds; import com.eu.habbo.habbohotel.rooms.Room; import com.eu.habbo.habbohotel.users.HabboItem; import com.eu.habbo.messages.incoming.MessageHandler; +import gnu.trove.map.hash.THashMap; + +import java.util.Map; public class AdvertisingSaveEvent extends MessageHandler { @Override @@ -26,6 +29,7 @@ public class AdvertisingSaveEvent extends MessageHandler { return; } if (item instanceof InteractionCustomValues) { + THashMap oldValues = new THashMap<>(((InteractionCustomValues) item).values); int count = this.packet.readInt(); for (int i = 0; i < count / 2; i++) { String key = this.packet.readString(); @@ -42,7 +46,7 @@ public class AdvertisingSaveEvent extends MessageHandler { item.needsUpdate(true); Emulator.getThreading().run(item); room.updateItem(item); - ((InteractionCustomValues) item).onCustomValuesSaved(room, this.client); + ((InteractionCustomValues) item).onCustomValuesSaved(room, this.client, oldValues); } } } diff --git a/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RoomPlaceItemEvent.java b/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RoomPlaceItemEvent.java index 8cdeb7d0..0f293184 100644 --- a/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RoomPlaceItemEvent.java +++ b/src/main/java/com/eu/habbo/messages/incoming/rooms/items/RoomPlaceItemEvent.java @@ -3,10 +3,7 @@ package com.eu.habbo.messages.incoming.rooms.items; import com.eu.habbo.habbohotel.items.FurnitureType; import com.eu.habbo.habbohotel.items.interactions.*; import com.eu.habbo.habbohotel.modtool.ScripterManager; -import com.eu.habbo.habbohotel.rooms.FurnitureMovementError; -import com.eu.habbo.habbohotel.rooms.Room; -import com.eu.habbo.habbohotel.rooms.RoomLayout; -import com.eu.habbo.habbohotel.rooms.RoomTile; +import com.eu.habbo.habbohotel.rooms.*; import com.eu.habbo.habbohotel.users.HabboItem; import com.eu.habbo.messages.incoming.MessageHandler; import com.eu.habbo.messages.outgoing.generic.alerts.BubbleAlertComposer; @@ -20,7 +17,7 @@ public class RoomPlaceItemEvent extends MessageHandler { int itemId = -1; - if (values.length != 0) itemId = Integer.valueOf(values[0]); + if (values.length != 0) itemId = Integer.parseInt(values[0]); if (!this.client.getHabbo().getRoomUnit().isInRoom()) { this.client.sendResponse(new BubbleAlertComposer(BubbleAlertKeys.FURNITURE_PLACEMENT_ERROR.key, FurnitureMovementError.NO_RIGHTS.errorCode)); @@ -56,27 +53,9 @@ public class RoomPlaceItemEvent extends MessageHandler { } if (item.getBaseItem().getType() == FurnitureType.FLOOR) { - short x = Short.valueOf(values[1]); - short y = Short.valueOf(values[2]); - int rotation = Integer.valueOf(values[3]); - if (rentSpace != null && !room.hasRights(this.client.getHabbo())) { - if (item instanceof InteractionRoller || - item instanceof InteractionStackHelper || - item instanceof InteractionWired || - item instanceof InteractionBackgroundToner || - item instanceof InteractionRoomAds || - item instanceof InteractionCannon || - item instanceof InteractionPuzzleBox || - item.getBaseItem().getType() == FurnitureType.WALL) { - this.client.sendResponse(new BubbleAlertComposer(BubbleAlertKeys.FURNITURE_PLACEMENT_ERROR.key, FurnitureMovementError.NO_RIGHTS.errorCode)); - return; - } - - if (!RoomLayout.squareInSquare(RoomLayout.getRectangle(rentSpace.getX(), rentSpace.getY(), rentSpace.getBaseItem().getWidth(), rentSpace.getBaseItem().getLength(), rentSpace.getRotation()), RoomLayout.getRectangle(x, y, item.getBaseItem().getWidth(), item.getBaseItem().getLength(), rotation))) { - this.client.sendResponse(new BubbleAlertComposer(BubbleAlertKeys.FURNITURE_PLACEMENT_ERROR.key, FurnitureMovementError.NO_RIGHTS.errorCode)); - return; - } - } + short x = Short.parseShort(values[1]); + short y = Short.parseShort(values[2]); + int rotation = Integer.parseInt(values[3]); RoomTile tile = room.getLayout().getTile(x, y); @@ -88,6 +67,30 @@ public class RoomPlaceItemEvent extends MessageHandler { return; } + HabboItem buildArea = null; + for (HabboItem area : room.getRoomSpecialTypes().getItemsOfType(InteractionBuildArea.class)) { + if (((InteractionBuildArea) area).inSquare(tile)) { + buildArea = area; + } + } + + if ((rentSpace != null || buildArea != null) && !room.hasRights(this.client.getHabbo())) { + if (item instanceof InteractionRoller || + item instanceof InteractionStackHelper || + item instanceof InteractionWired || + item instanceof InteractionBackgroundToner || + item instanceof InteractionRoomAds || + item instanceof InteractionCannon || + item instanceof InteractionPuzzleBox || + item.getBaseItem().getType() == FurnitureType.WALL) { + this.client.sendResponse(new BubbleAlertComposer(BubbleAlertKeys.FURNITURE_PLACEMENT_ERROR.key, FurnitureMovementError.NO_RIGHTS.errorCode)); + return; + } + if (rentSpace != null && !RoomLayout.squareInSquare(RoomLayout.getRectangle(rentSpace.getX(), rentSpace.getY(), rentSpace.getBaseItem().getWidth(), rentSpace.getBaseItem().getLength(), rentSpace.getRotation()), RoomLayout.getRectangle(x, y, item.getBaseItem().getWidth(), item.getBaseItem().getLength(), rotation))) { + this.client.sendResponse(new BubbleAlertComposer(BubbleAlertKeys.FURNITURE_PLACEMENT_ERROR.key, FurnitureMovementError.NO_RIGHTS.errorCode)); + return; + } + } FurnitureMovementError error = room.canPlaceFurnitureAt(item, this.client.getHabbo(), tile, rotation); if (!error.equals(FurnitureMovementError.NONE)) {