You've already forked Arcturus-Morningstar-Extended
mirror of
https://github.com/duckietm/Arcturus-Morningstar-Extended.git
synced 2026-06-20 15:36:17 +00:00
🆙 updated the wireds for selecotrs and added wf_slc_users_neighborhood
This commit is contained in:
@@ -49,6 +49,7 @@ import com.eu.habbo.habbohotel.items.interactions.wired.conditions.*;
|
|||||||
import com.eu.habbo.habbohotel.items.interactions.wired.effects.*;
|
import com.eu.habbo.habbohotel.items.interactions.wired.effects.*;
|
||||||
import com.eu.habbo.habbohotel.items.interactions.wired.selector.WiredEffectFurniArea;
|
import com.eu.habbo.habbohotel.items.interactions.wired.selector.WiredEffectFurniArea;
|
||||||
import com.eu.habbo.habbohotel.items.interactions.wired.selector.WiredEffectUsersArea;
|
import com.eu.habbo.habbohotel.items.interactions.wired.selector.WiredEffectUsersArea;
|
||||||
|
import com.eu.habbo.habbohotel.items.interactions.wired.selector.WiredEffectUsersNeighborhood;
|
||||||
import com.eu.habbo.habbohotel.items.interactions.wired.selector.WiredEffectFurniNeighborhood;
|
import com.eu.habbo.habbohotel.items.interactions.wired.selector.WiredEffectFurniNeighborhood;
|
||||||
import com.eu.habbo.habbohotel.items.interactions.wired.selector.WiredEffectFurniByType;
|
import com.eu.habbo.habbohotel.items.interactions.wired.selector.WiredEffectFurniByType;
|
||||||
import com.eu.habbo.habbohotel.items.interactions.wired.extra.WiredBlob;
|
import com.eu.habbo.habbohotel.items.interactions.wired.extra.WiredBlob;
|
||||||
@@ -256,6 +257,7 @@ public class ItemManager {
|
|||||||
this.interactionsList.add(new ItemInteraction("wf_slc_furni_neighborhood", WiredEffectFurniNeighborhood.class));
|
this.interactionsList.add(new ItemInteraction("wf_slc_furni_neighborhood", WiredEffectFurniNeighborhood.class));
|
||||||
this.interactionsList.add(new ItemInteraction("wf_slc_furni_bytype", WiredEffectFurniByType.class));
|
this.interactionsList.add(new ItemInteraction("wf_slc_furni_bytype", WiredEffectFurniByType.class));
|
||||||
this.interactionsList.add(new ItemInteraction("wf_slc_users_area", WiredEffectUsersArea.class));
|
this.interactionsList.add(new ItemInteraction("wf_slc_users_area", WiredEffectUsersArea.class));
|
||||||
|
this.interactionsList.add(new ItemInteraction("wf_slc_users_neighborhood", WiredEffectUsersNeighborhood.class));
|
||||||
|
|
||||||
this.interactionsList.add(new ItemInteraction("wf_cnd_has_furni_on", WiredConditionFurniHaveFurni.class));
|
this.interactionsList.add(new ItemInteraction("wf_cnd_has_furni_on", WiredConditionFurniHaveFurni.class));
|
||||||
this.interactionsList.add(new ItemInteraction("wf_cnd_furnis_hv_avtrs", WiredConditionFurniHaveHabbo.class));
|
this.interactionsList.add(new ItemInteraction("wf_cnd_furnis_hv_avtrs", WiredConditionFurniHaveHabbo.class));
|
||||||
|
|||||||
+23
-21
@@ -86,9 +86,10 @@ public class WiredEffectBotTeleport extends InteractionWiredEffect {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void serializeWiredData(ServerMessage message, Room room) {
|
public void serializeWiredData(ServerMessage message, Room room) {
|
||||||
|
List<HabboItem> itemsSnapshot = new ArrayList<>(this.items);
|
||||||
THashSet<HabboItem> items = new THashSet<>();
|
THashSet<HabboItem> items = new THashSet<>();
|
||||||
|
|
||||||
for (HabboItem item : this.items) {
|
for (HabboItem item : itemsSnapshot) {
|
||||||
if (item.getRoomId() != this.getRoomId() || Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null)
|
if (item.getRoomId() != this.getRoomId() || Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null)
|
||||||
items.add(item);
|
items.add(item);
|
||||||
}
|
}
|
||||||
@@ -97,10 +98,11 @@ public class WiredEffectBotTeleport extends InteractionWiredEffect {
|
|||||||
this.items.remove(item);
|
this.items.remove(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
itemsSnapshot = new ArrayList<>(this.items);
|
||||||
message.appendBoolean(false);
|
message.appendBoolean(false);
|
||||||
message.appendInt(WiredManager.MAXIMUM_FURNI_SELECTION);
|
message.appendInt(WiredManager.MAXIMUM_FURNI_SELECTION);
|
||||||
message.appendInt(this.items.size());
|
message.appendInt(itemsSnapshot.size());
|
||||||
for (HabboItem item : this.items)
|
for (HabboItem item : itemsSnapshot)
|
||||||
message.appendInt(item.getId());
|
message.appendInt(item.getId());
|
||||||
|
|
||||||
message.appendInt(this.getBaseItem().getSpriteId());
|
message.appendInt(this.getBaseItem().getSpriteId());
|
||||||
@@ -156,11 +158,18 @@ public class WiredEffectBotTeleport extends InteractionWiredEffect {
|
|||||||
public void execute(WiredContext ctx) {
|
public void execute(WiredContext ctx) {
|
||||||
Room room = ctx.room();
|
Room room = ctx.room();
|
||||||
|
|
||||||
if (this.items.isEmpty())
|
// Use selector targets if a selector has modified them, otherwise use manually picked items
|
||||||
return;
|
Iterable<HabboItem> effectiveItems = ctx.targets().isItemsModifiedBySelector()
|
||||||
|
? ctx.targets().items()
|
||||||
|
: new ArrayList<>(this.items);
|
||||||
|
|
||||||
if (room.getLayout() == null)
|
List<HabboItem> validItems = new ArrayList<>();
|
||||||
return;
|
for (HabboItem item : effectiveItems) {
|
||||||
|
if (item != null && item.getRoomId() != 0) validItems.add(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (validItems.isEmpty()) return;
|
||||||
|
if (room.getLayout() == null) return;
|
||||||
|
|
||||||
List<Bot> bots = room.getBots(this.botName);
|
List<Bot> bots = room.getBots(this.botName);
|
||||||
|
|
||||||
@@ -170,20 +179,12 @@ public class WiredEffectBotTeleport extends InteractionWiredEffect {
|
|||||||
|
|
||||||
Bot bot = bots.get(0);
|
Bot bot = bots.get(0);
|
||||||
|
|
||||||
int i = Emulator.getRandom().nextInt(this.items.size()) + 1;
|
HabboItem targetItem = validItems.get(Emulator.getRandom().nextInt(validItems.size()));
|
||||||
int j = 1;
|
|
||||||
|
|
||||||
for (HabboItem item : this.items) {
|
if (targetItem.getRoomId() == bot.getRoom().getId()) {
|
||||||
if (item.getRoomId() != 0 && item.getRoomId() == bot.getRoom().getId()) {
|
RoomTile tile = room.getLayout().getTile(targetItem.getX(), targetItem.getY());
|
||||||
if (i == j) {
|
if (tile != null) {
|
||||||
RoomTile tile = room.getLayout().getTile(item.getX(), item.getY());
|
teleportUnitToTile(bot.getRoomUnit(), tile);
|
||||||
if (tile != null) {
|
|
||||||
teleportUnitToTile(bot.getRoomUnit(), tile);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -199,7 +200,8 @@ public class WiredEffectBotTeleport extends InteractionWiredEffect {
|
|||||||
ArrayList<Integer> itemIds = new ArrayList<>();
|
ArrayList<Integer> itemIds = new ArrayList<>();
|
||||||
|
|
||||||
if (this.items != null) {
|
if (this.items != null) {
|
||||||
for (HabboItem item : this.items) {
|
List<HabboItem> itemsSnapshot = new ArrayList<>(this.items);
|
||||||
|
for (HabboItem item : itemsSnapshot) {
|
||||||
if (item.getRoomId() != 0) {
|
if (item.getRoomId() != 0) {
|
||||||
itemIds.add(item.getId());
|
itemIds.add(item.getId());
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-3
@@ -111,15 +111,25 @@ public class WiredEffectBotWalkToFurni extends InteractionWiredEffect {
|
|||||||
Room room = ctx.room();
|
Room room = ctx.room();
|
||||||
List<Bot> bots = room.getBots(this.botName);
|
List<Bot> bots = room.getBots(this.botName);
|
||||||
|
|
||||||
if (this.items.isEmpty() || bots.size() != 1) {
|
// Use selector targets if a selector has modified them, otherwise use manually picked items
|
||||||
|
boolean useSelector = ctx.targets().isItemsModifiedBySelector();
|
||||||
|
List<HabboItem> effectiveItems;
|
||||||
|
|
||||||
|
if (useSelector) {
|
||||||
|
effectiveItems = new ArrayList<>(ctx.targets().items());
|
||||||
|
} else {
|
||||||
|
this.items.removeIf(item -> item == null || item.getRoomId() != this.getRoomId() || Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null);
|
||||||
|
effectiveItems = this.items;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (effectiveItems.isEmpty() || bots.size() != 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bot bot = bots.get(0);
|
Bot bot = bots.get(0);
|
||||||
this.items.removeIf(item -> item == null || item.getRoomId() != this.getRoomId() || Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null);
|
|
||||||
|
|
||||||
// Bots shouldn't walk to the tile they are already standing on
|
// Bots shouldn't walk to the tile they are already standing on
|
||||||
List<HabboItem> possibleItems = this.items.stream()
|
List<HabboItem> possibleItems = effectiveItems.stream()
|
||||||
.filter(item -> !room.getBotsOnItem(item).contains(bot))
|
.filter(item -> !room.getBotsOnItem(item).contains(bot))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
|||||||
+28
-11
@@ -50,20 +50,37 @@ public class WiredEffectChangeFurniDirection extends InteractionWiredEffect {
|
|||||||
Room room = ctx.room();
|
Room room = ctx.room();
|
||||||
if (room == null || room.getLayout() == null) return;
|
if (room == null || room.getLayout() == null) return;
|
||||||
|
|
||||||
THashSet<HabboItem> items = new THashSet<>();
|
// Use selector targets if a selector has modified them, otherwise use manually picked items
|
||||||
|
boolean useSelector = ctx.targets().isItemsModifiedBySelector();
|
||||||
|
THashMap<HabboItem, WiredChangeDirectionSetting> effectiveItems;
|
||||||
|
|
||||||
for (HabboItem item : this.items.keySet()) {
|
if (useSelector) {
|
||||||
if (item == null || Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null)
|
effectiveItems = new THashMap<>();
|
||||||
items.add(item);
|
for (HabboItem item : ctx.targets().items()) {
|
||||||
|
if (item != null) {
|
||||||
|
// Check if we already have settings for this item, otherwise create defaults
|
||||||
|
WiredChangeDirectionSetting setting = this.items.get(item);
|
||||||
|
if (setting == null) {
|
||||||
|
setting = new WiredChangeDirectionSetting(item.getId(), item.getRotation(), this.startRotation);
|
||||||
|
}
|
||||||
|
effectiveItems.put(item, setting);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
THashSet<HabboItem> toRemove = new THashSet<>();
|
||||||
|
for (HabboItem item : this.items.keySet()) {
|
||||||
|
if (item == null || Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null)
|
||||||
|
toRemove.add(item);
|
||||||
|
}
|
||||||
|
for (HabboItem item : toRemove) {
|
||||||
|
this.items.remove(item);
|
||||||
|
}
|
||||||
|
effectiveItems = this.items;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (HabboItem item : items) {
|
if (effectiveItems.isEmpty()) return;
|
||||||
this.items.remove(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.items.isEmpty()) return;
|
for (Map.Entry<HabboItem, WiredChangeDirectionSetting> entry : effectiveItems.entrySet()) {
|
||||||
|
|
||||||
for (Map.Entry<HabboItem, WiredChangeDirectionSetting> entry : this.items.entrySet()) {
|
|
||||||
HabboItem item = entry.getKey();
|
HabboItem item = entry.getKey();
|
||||||
if (item == null || entry.getValue() == null) continue;
|
if (item == null || entry.getValue() == null) continue;
|
||||||
|
|
||||||
@@ -85,7 +102,7 @@ public class WiredEffectChangeFurniDirection extends InteractionWiredEffect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Map.Entry<HabboItem, WiredChangeDirectionSetting> entry : this.items.entrySet()) {
|
for (Map.Entry<HabboItem, WiredChangeDirectionSetting> entry : effectiveItems.entrySet()) {
|
||||||
HabboItem item = entry.getKey();
|
HabboItem item = entry.getKey();
|
||||||
if (item == null || entry.getValue() == null) continue;
|
if (item == null || entry.getValue() == null) continue;
|
||||||
|
|
||||||
|
|||||||
+9
@@ -21,12 +21,16 @@ import com.eu.habbo.messages.outgoing.rooms.users.RoomUserWhisperComposer;
|
|||||||
import com.eu.habbo.threading.runnables.RoomUnitKick;
|
import com.eu.habbo.threading.runnables.RoomUnitKick;
|
||||||
import gnu.trove.procedure.TObjectProcedure;
|
import gnu.trove.procedure.TObjectProcedure;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class WiredEffectKickHabbo extends InteractionWiredEffect {
|
public class WiredEffectKickHabbo extends InteractionWiredEffect {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(WiredEffectKickHabbo.class);
|
||||||
public static final WiredEffectType type = WiredEffectType.KICK_USER;
|
public static final WiredEffectType type = WiredEffectType.KICK_USER;
|
||||||
|
|
||||||
private String message = "";
|
private String message = "";
|
||||||
@@ -43,8 +47,13 @@ public class WiredEffectKickHabbo extends InteractionWiredEffect {
|
|||||||
public void execute(WiredContext ctx) {
|
public void execute(WiredContext ctx) {
|
||||||
Room room = ctx.room();
|
Room room = ctx.room();
|
||||||
|
|
||||||
|
LOGGER.debug("[KickHabbo] targets.users().size={} usersModifiedBySelector={}",
|
||||||
|
ctx.targets().users().size(), ctx.targets().isUsersModifiedBySelector());
|
||||||
|
|
||||||
for (RoomUnit unit : ctx.targets().users()) {
|
for (RoomUnit unit : ctx.targets().users()) {
|
||||||
Habbo habbo = room.getHabbo(unit);
|
Habbo habbo = room.getHabbo(unit);
|
||||||
|
LOGGER.debug("[KickHabbo] RoomUnit id={} type={} -> Habbo={}", unit.getId(), unit.getRoomUnitType(),
|
||||||
|
habbo != null ? habbo.getHabboInfo().getUsername() : "null");
|
||||||
if (habbo == null) continue;
|
if (habbo == null) continue;
|
||||||
|
|
||||||
if (habbo.hasPermission(Permission.ACC_UNKICKABLE)) {
|
if (habbo.hasPermission(Permission.ACC_UNKICKABLE)) {
|
||||||
|
|||||||
+12
@@ -55,7 +55,19 @@ public class WiredEffectMatchFurni extends InteractionWiredEffect implements Int
|
|||||||
if (room.getLayout() == null)
|
if (room.getLayout() == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// When a selector provides items, only apply matching to items in both the selector targets and settings
|
||||||
|
boolean useSelector = ctx.targets().isItemsModifiedBySelector();
|
||||||
|
java.util.Set<Integer> selectorItemIds = null;
|
||||||
|
if (useSelector) {
|
||||||
|
selectorItemIds = new java.util.HashSet<>();
|
||||||
|
for (HabboItem si : ctx.targets().items()) {
|
||||||
|
selectorItemIds.add(si.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (WiredMatchFurniSetting setting : this.settings) {
|
for (WiredMatchFurniSetting setting : this.settings) {
|
||||||
|
if (useSelector && !selectorItemIds.contains(setting.item_id)) continue;
|
||||||
|
|
||||||
HabboItem item = room.getHabboItem(setting.item_id);
|
HabboItem item = room.getHabboItem(setting.item_id);
|
||||||
if (item != null) {
|
if (item != null) {
|
||||||
if (this.state && (this.checkForWiredResetPermission && item.allowWiredResetState())) {
|
if (this.state && (this.checkForWiredResetPermission && item.allowWiredResetState())) {
|
||||||
|
|||||||
+24
-12
@@ -23,6 +23,7 @@ import java.util.Comparator;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
|
||||||
public class WiredEffectMoveFurniAway extends InteractionWiredEffect {
|
public class WiredEffectMoveFurniAway extends InteractionWiredEffect {
|
||||||
public static final WiredEffectType type = WiredEffectType.FLEE;
|
public static final WiredEffectType type = WiredEffectType.FLEE;
|
||||||
|
|
||||||
@@ -41,16 +42,24 @@ public class WiredEffectMoveFurniAway extends InteractionWiredEffect {
|
|||||||
Room room = ctx.room();
|
Room room = ctx.room();
|
||||||
if (room.getLayout() == null) return;
|
if (room.getLayout() == null) return;
|
||||||
|
|
||||||
THashSet<HabboItem> items = new THashSet<>();
|
// Use selector targets if a selector has modified them, otherwise use manually picked items
|
||||||
|
boolean useSelector = ctx.targets().isItemsModifiedBySelector();
|
||||||
|
Iterable<HabboItem> effectiveItems;
|
||||||
|
|
||||||
for (HabboItem item : this.items) {
|
if (useSelector) {
|
||||||
if (item.getRoomId() == 0)
|
effectiveItems = ctx.targets().items();
|
||||||
items.add(item);
|
} else {
|
||||||
|
THashSet<HabboItem> toRemove = new THashSet<>();
|
||||||
|
List<HabboItem> itemsSnapshot = new ArrayList<>(this.items);
|
||||||
|
for (HabboItem item : itemsSnapshot) {
|
||||||
|
if (item.getRoomId() == 0)
|
||||||
|
toRemove.add(item);
|
||||||
|
}
|
||||||
|
this.items.removeAll(toRemove);
|
||||||
|
effectiveItems = new ArrayList<>(this.items);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.items.removeAll(items);
|
for (HabboItem item : effectiveItems) {
|
||||||
|
|
||||||
for (HabboItem item : this.items) {
|
|
||||||
if (item == null) continue;
|
if (item == null) continue;
|
||||||
|
|
||||||
RoomTile t = room.getLayout().getTile(item.getX(), item.getY());
|
RoomTile t = room.getLayout().getTile(item.getX(), item.getY());
|
||||||
@@ -115,7 +124,7 @@ public class WiredEffectMoveFurniAway extends InteractionWiredEffect {
|
|||||||
Room room = ctx.room();
|
Room room = ctx.room();
|
||||||
if (room.getLayout() == null) return true;
|
if (room.getLayout() == null) return true;
|
||||||
|
|
||||||
for (HabboItem item : this.items) {
|
for (HabboItem item : new ArrayList<>(this.items)) {
|
||||||
if (item == null) continue;
|
if (item == null) continue;
|
||||||
|
|
||||||
WiredSimulation.SimulatedPosition currentPos = simulation.getItemPosition(item);
|
WiredSimulation.SimulatedPosition currentPos = simulation.getItemPosition(item);
|
||||||
@@ -158,9 +167,10 @@ public class WiredEffectMoveFurniAway extends InteractionWiredEffect {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getWiredData() {
|
public String getWiredData() {
|
||||||
|
List<HabboItem> itemsSnapshot = new ArrayList<>(this.items);
|
||||||
return WiredManager.getGson().toJson(new JsonData(
|
return WiredManager.getGson().toJson(new JsonData(
|
||||||
this.getDelay(),
|
this.getDelay(),
|
||||||
this.items.stream().map(HabboItem::getId).collect(Collectors.toList())
|
itemsSnapshot.stream().map(HabboItem::getId).collect(Collectors.toList())
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,9 +220,10 @@ public class WiredEffectMoveFurniAway extends InteractionWiredEffect {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void serializeWiredData(ServerMessage message, Room room) {
|
public void serializeWiredData(ServerMessage message, Room room) {
|
||||||
|
List<HabboItem> itemsSnapshot = new ArrayList<>(this.items);
|
||||||
THashSet<HabboItem> items = new THashSet<>();
|
THashSet<HabboItem> items = new THashSet<>();
|
||||||
|
|
||||||
for (HabboItem item : this.items) {
|
for (HabboItem item : itemsSnapshot) {
|
||||||
if (item.getRoomId() != this.getRoomId() || Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null)
|
if (item.getRoomId() != this.getRoomId() || Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null)
|
||||||
items.add(item);
|
items.add(item);
|
||||||
}
|
}
|
||||||
@@ -220,10 +231,11 @@ public class WiredEffectMoveFurniAway extends InteractionWiredEffect {
|
|||||||
for (HabboItem item : items) {
|
for (HabboItem item : items) {
|
||||||
this.items.remove(item);
|
this.items.remove(item);
|
||||||
}
|
}
|
||||||
|
itemsSnapshot = new ArrayList<>(this.items);
|
||||||
message.appendBoolean(false);
|
message.appendBoolean(false);
|
||||||
message.appendInt(WiredManager.MAXIMUM_FURNI_SELECTION);
|
message.appendInt(WiredManager.MAXIMUM_FURNI_SELECTION);
|
||||||
message.appendInt(this.items.size());
|
message.appendInt(itemsSnapshot.size());
|
||||||
for (HabboItem item : this.items)
|
for (HabboItem item : itemsSnapshot)
|
||||||
message.appendInt(item.getId());
|
message.appendInt(item.getId());
|
||||||
|
|
||||||
message.appendInt(this.getBaseItem().getSpriteId());
|
message.appendInt(this.getBaseItem().getSpriteId());
|
||||||
|
|||||||
+27
-15
@@ -75,25 +75,33 @@ public class WiredEffectMoveFurniTo extends InteractionWiredEffect {
|
|||||||
Room room = ctx.room();
|
Room room = ctx.room();
|
||||||
if (room == null || room.getLayout() == null) return;
|
if (room == null || room.getLayout() == null) return;
|
||||||
|
|
||||||
List<HabboItem> items = new ArrayList<>();
|
// Use selector targets if a selector has modified them, otherwise use manually picked items
|
||||||
|
boolean useSelector = ctx.targets().isItemsModifiedBySelector();
|
||||||
|
List<HabboItem> effectiveItems;
|
||||||
|
|
||||||
for (HabboItem item : this.items) {
|
if (useSelector) {
|
||||||
if (item == null || Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null)
|
effectiveItems = new ArrayList<>(ctx.targets().items());
|
||||||
items.add(item);
|
} else {
|
||||||
|
List<HabboItem> toRemove = new ArrayList<>();
|
||||||
|
List<HabboItem> itemsSnapshot = new ArrayList<>(this.items);
|
||||||
|
for (HabboItem item : itemsSnapshot) {
|
||||||
|
if (item == null || Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null)
|
||||||
|
toRemove.add(item);
|
||||||
|
}
|
||||||
|
for (HabboItem item : toRemove) {
|
||||||
|
this.items.remove(item);
|
||||||
|
}
|
||||||
|
effectiveItems = new ArrayList<>(this.items);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (HabboItem item : items) {
|
if (effectiveItems.isEmpty())
|
||||||
this.items.remove(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.items.isEmpty())
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Object[] stuff = ctx.legacySettings();
|
Object[] stuff = ctx.legacySettings();
|
||||||
if (stuff != null && stuff.length > 0) {
|
if (stuff != null && stuff.length > 0) {
|
||||||
for (Object object : stuff) {
|
for (Object object : stuff) {
|
||||||
if (object instanceof HabboItem) {
|
if (object instanceof HabboItem) {
|
||||||
HabboItem targetItem = this.items.get(Emulator.getRandom().nextInt(this.items.size()));
|
HabboItem targetItem = effectiveItems.get(Emulator.getRandom().nextInt(effectiveItems.size()));
|
||||||
|
|
||||||
if (targetItem != null) {
|
if (targetItem != null) {
|
||||||
int indexOffset = 0;
|
int indexOffset = 0;
|
||||||
@@ -181,8 +189,9 @@ public class WiredEffectMoveFurniTo extends InteractionWiredEffect {
|
|||||||
@Override
|
@Override
|
||||||
public String getWiredData() {
|
public String getWiredData() {
|
||||||
THashSet<HabboItem> itemsToRemove = new THashSet<>();
|
THashSet<HabboItem> itemsToRemove = new THashSet<>();
|
||||||
|
List<HabboItem> itemsSnapshot = new ArrayList<>(this.items);
|
||||||
|
|
||||||
for (HabboItem item : this.items) {
|
for (HabboItem item : itemsSnapshot) {
|
||||||
if (item.getRoomId() != this.getRoomId() || Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null)
|
if (item.getRoomId() != this.getRoomId() || Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null)
|
||||||
itemsToRemove.add(item);
|
itemsToRemove.add(item);
|
||||||
}
|
}
|
||||||
@@ -191,19 +200,21 @@ public class WiredEffectMoveFurniTo extends InteractionWiredEffect {
|
|||||||
this.items.remove(item);
|
this.items.remove(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
itemsSnapshot = new ArrayList<>(this.items);
|
||||||
return WiredManager.getGson().toJson(new JsonData(
|
return WiredManager.getGson().toJson(new JsonData(
|
||||||
this.direction,
|
this.direction,
|
||||||
this.spacing,
|
this.spacing,
|
||||||
this.getDelay(),
|
this.getDelay(),
|
||||||
this.items.stream().map(HabboItem::getId).collect(Collectors.toList())
|
itemsSnapshot.stream().map(HabboItem::getId).collect(Collectors.toList())
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void serializeWiredData(ServerMessage message, Room room) {
|
public void serializeWiredData(ServerMessage message, Room room) {
|
||||||
|
List<HabboItem> itemsSnapshot = new ArrayList<>(this.items);
|
||||||
THashSet<HabboItem> items = new THashSet<>();
|
THashSet<HabboItem> items = new THashSet<>();
|
||||||
|
|
||||||
for (HabboItem item : this.items) {
|
for (HabboItem item : itemsSnapshot) {
|
||||||
if (item.getRoomId() != this.getRoomId() || Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null)
|
if (item.getRoomId() != this.getRoomId() || Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null)
|
||||||
items.add(item);
|
items.add(item);
|
||||||
}
|
}
|
||||||
@@ -212,10 +223,11 @@ public class WiredEffectMoveFurniTo extends InteractionWiredEffect {
|
|||||||
this.items.remove(item);
|
this.items.remove(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
itemsSnapshot = new ArrayList<>(this.items);
|
||||||
message.appendBoolean(false);
|
message.appendBoolean(false);
|
||||||
message.appendInt(WiredManager.MAXIMUM_FURNI_SELECTION);
|
message.appendInt(WiredManager.MAXIMUM_FURNI_SELECTION);
|
||||||
message.appendInt(this.items.size());
|
message.appendInt(itemsSnapshot.size());
|
||||||
for (HabboItem item : this.items)
|
for (HabboItem item : itemsSnapshot)
|
||||||
message.appendInt(item.getId());
|
message.appendInt(item.getId());
|
||||||
message.appendInt(this.getBaseItem().getSpriteId());
|
message.appendInt(this.getBaseItem().getSpriteId());
|
||||||
message.appendInt(this.getId());
|
message.appendInt(this.getId());
|
||||||
|
|||||||
+25
-14
@@ -90,18 +90,26 @@ public class WiredEffectMoveFurniTowards extends InteractionWiredEffect {
|
|||||||
public void execute(WiredContext ctx) {
|
public void execute(WiredContext ctx) {
|
||||||
Room room = ctx.room();
|
Room room = ctx.room();
|
||||||
|
|
||||||
THashSet<HabboItem> items = new THashSet<>();
|
// Use selector targets if a selector has modified them, otherwise use manually picked items
|
||||||
|
boolean useSelector = ctx.targets().isItemsModifiedBySelector();
|
||||||
|
Iterable<HabboItem> effectiveItems;
|
||||||
|
|
||||||
for (HabboItem item : this.items) {
|
if (useSelector) {
|
||||||
if (Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null)
|
effectiveItems = ctx.targets().items();
|
||||||
items.add(item);
|
} else {
|
||||||
|
THashSet<HabboItem> toRemove = new THashSet<>();
|
||||||
|
List<HabboItem> itemsSnapshot = new ArrayList<>(this.items);
|
||||||
|
for (HabboItem item : itemsSnapshot) {
|
||||||
|
if (Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null)
|
||||||
|
toRemove.add(item);
|
||||||
|
}
|
||||||
|
for (HabboItem item : toRemove) {
|
||||||
|
this.items.remove(item);
|
||||||
|
}
|
||||||
|
effectiveItems = new ArrayList<>(this.items);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (HabboItem item : items) {
|
for (HabboItem item : effectiveItems) {
|
||||||
this.items.remove(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (HabboItem item : this.items) {
|
|
||||||
|
|
||||||
if (item == null)
|
if (item == null)
|
||||||
continue;
|
continue;
|
||||||
@@ -249,7 +257,7 @@ public class WiredEffectMoveFurniTowards extends InteractionWiredEffect {
|
|||||||
RoomLayout layout = room.getLayout();
|
RoomLayout layout = room.getLayout();
|
||||||
if (layout == null) return true;
|
if (layout == null) return true;
|
||||||
|
|
||||||
for (HabboItem item : this.items) {
|
for (HabboItem item : new ArrayList<>(this.items)) {
|
||||||
if (item == null) continue;
|
if (item == null) continue;
|
||||||
|
|
||||||
WiredSimulation.SimulatedPosition currentPos = simulation.getItemPosition(item);
|
WiredSimulation.SimulatedPosition currentPos = simulation.getItemPosition(item);
|
||||||
@@ -311,9 +319,10 @@ public class WiredEffectMoveFurniTowards extends InteractionWiredEffect {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getWiredData() {
|
public String getWiredData() {
|
||||||
|
List<HabboItem> itemsSnapshot = new ArrayList<>(this.items);
|
||||||
return WiredManager.getGson().toJson(new JsonData(
|
return WiredManager.getGson().toJson(new JsonData(
|
||||||
this.getDelay(),
|
this.getDelay(),
|
||||||
this.items.stream().map(HabboItem::getId).collect(Collectors.toList())
|
itemsSnapshot.stream().map(HabboItem::getId).collect(Collectors.toList())
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -364,9 +373,10 @@ public class WiredEffectMoveFurniTowards extends InteractionWiredEffect {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void serializeWiredData(ServerMessage message, Room room) {
|
public void serializeWiredData(ServerMessage message, Room room) {
|
||||||
|
List<HabboItem> itemsSnapshot = new ArrayList<>(this.items);
|
||||||
THashSet<HabboItem> items = new THashSet<>();
|
THashSet<HabboItem> items = new THashSet<>();
|
||||||
|
|
||||||
for (HabboItem item : this.items) {
|
for (HabboItem item : itemsSnapshot) {
|
||||||
if (item.getRoomId() != this.getRoomId() || Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null)
|
if (item.getRoomId() != this.getRoomId() || Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null)
|
||||||
items.add(item);
|
items.add(item);
|
||||||
}
|
}
|
||||||
@@ -374,10 +384,11 @@ public class WiredEffectMoveFurniTowards extends InteractionWiredEffect {
|
|||||||
for (HabboItem item : items) {
|
for (HabboItem item : items) {
|
||||||
this.items.remove(item);
|
this.items.remove(item);
|
||||||
}
|
}
|
||||||
|
itemsSnapshot = new ArrayList<>(this.items);
|
||||||
message.appendBoolean(false);
|
message.appendBoolean(false);
|
||||||
message.appendInt(WiredManager.MAXIMUM_FURNI_SELECTION);
|
message.appendInt(WiredManager.MAXIMUM_FURNI_SELECTION);
|
||||||
message.appendInt(this.items.size());
|
message.appendInt(itemsSnapshot.size());
|
||||||
for (HabboItem item : this.items)
|
for (HabboItem item : itemsSnapshot)
|
||||||
message.appendInt(item.getId());
|
message.appendInt(item.getId());
|
||||||
|
|
||||||
message.appendInt(this.getBaseItem().getSpriteId());
|
message.appendInt(this.getBaseItem().getSpriteId());
|
||||||
|
|||||||
+13
-3
@@ -46,10 +46,20 @@ public class WiredEffectMoveRotateFurni extends InteractionWiredEffect implement
|
|||||||
@Override
|
@Override
|
||||||
public void execute(WiredContext ctx) {
|
public void execute(WiredContext ctx) {
|
||||||
Room room = ctx.room();
|
Room room = ctx.room();
|
||||||
// remove items that are no longer in the room
|
|
||||||
this.items.removeIf(item -> Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null);
|
|
||||||
|
|
||||||
for (HabboItem item : this.items) {
|
// Use selector targets if a selector has modified them, otherwise use manually picked items
|
||||||
|
boolean useSelector = ctx.targets().isItemsModifiedBySelector();
|
||||||
|
Iterable<HabboItem> effectiveItems;
|
||||||
|
|
||||||
|
if (useSelector) {
|
||||||
|
effectiveItems = ctx.targets().items();
|
||||||
|
} else {
|
||||||
|
// remove items that are no longer in the room
|
||||||
|
this.items.removeIf(item -> Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null);
|
||||||
|
effectiveItems = this.items;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (HabboItem item : effectiveItems) {
|
||||||
if(this.itemCooldowns.contains(item))
|
if(this.itemCooldowns.contains(item))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|||||||
+20
-9
@@ -113,9 +113,10 @@ public class WiredEffectTeleport extends InteractionWiredEffect {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void serializeWiredData(ServerMessage message, Room room) {
|
public void serializeWiredData(ServerMessage message, Room room) {
|
||||||
|
List<HabboItem> itemsSnapshot = new ArrayList<>(this.items);
|
||||||
THashSet<HabboItem> items = new THashSet<>();
|
THashSet<HabboItem> items = new THashSet<>();
|
||||||
|
|
||||||
for (HabboItem item : this.items) {
|
for (HabboItem item : itemsSnapshot) {
|
||||||
if (item.getRoomId() != this.getRoomId() || Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null)
|
if (item.getRoomId() != this.getRoomId() || Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null)
|
||||||
items.add(item);
|
items.add(item);
|
||||||
}
|
}
|
||||||
@@ -123,10 +124,11 @@ public class WiredEffectTeleport extends InteractionWiredEffect {
|
|||||||
for (HabboItem item : items) {
|
for (HabboItem item : items) {
|
||||||
this.items.remove(item);
|
this.items.remove(item);
|
||||||
}
|
}
|
||||||
|
itemsSnapshot = new ArrayList<>(this.items);
|
||||||
message.appendBoolean(false);
|
message.appendBoolean(false);
|
||||||
message.appendInt(WiredManager.MAXIMUM_FURNI_SELECTION);
|
message.appendInt(WiredManager.MAXIMUM_FURNI_SELECTION);
|
||||||
message.appendInt(this.items.size());
|
message.appendInt(itemsSnapshot.size());
|
||||||
for (HabboItem item : this.items)
|
for (HabboItem item : itemsSnapshot)
|
||||||
message.appendInt(item.getId());
|
message.appendInt(item.getId());
|
||||||
|
|
||||||
message.appendInt(this.getBaseItem().getSpriteId());
|
message.appendInt(this.getBaseItem().getSpriteId());
|
||||||
@@ -196,14 +198,22 @@ public class WiredEffectTeleport extends InteractionWiredEffect {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.items.removeIf(item -> item == null || item.getRoomId() != this.getRoomId()
|
// Use selector targets if a selector has modified them, otherwise use manually picked items
|
||||||
|| Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null);
|
List<HabboItem> effectiveItems;
|
||||||
|
|
||||||
if (this.items.isEmpty()) return;
|
if (ctx.targets().isItemsModifiedBySelector()) {
|
||||||
|
effectiveItems = new ArrayList<>(ctx.targets().items());
|
||||||
|
} else {
|
||||||
|
this.items.removeIf(item -> item == null || item.getRoomId() != this.getRoomId()
|
||||||
|
|| Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null);
|
||||||
|
effectiveItems = new ArrayList<>(this.items);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (effectiveItems.isEmpty()) return;
|
||||||
|
|
||||||
for (RoomUnit roomUnit : ctx.targets().users()) {
|
for (RoomUnit roomUnit : ctx.targets().users()) {
|
||||||
int i = Emulator.getRandom().nextInt(this.items.size());
|
int i = Emulator.getRandom().nextInt(effectiveItems.size());
|
||||||
HabboItem item = this.items.get(i);
|
HabboItem item = effectiveItems.get(i);
|
||||||
|
|
||||||
if (item == null) continue;
|
if (item == null) continue;
|
||||||
|
|
||||||
@@ -222,9 +232,10 @@ public class WiredEffectTeleport extends InteractionWiredEffect {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getWiredData() {
|
public String getWiredData() {
|
||||||
|
List<HabboItem> itemsSnapshot = new ArrayList<>(this.items);
|
||||||
return WiredManager.getGson().toJson(new JsonData(
|
return WiredManager.getGson().toJson(new JsonData(
|
||||||
this.getDelay(),
|
this.getDelay(),
|
||||||
this.items.stream().map(HabboItem::getId).collect(Collectors.toList())
|
itemsSnapshot.stream().map(HabboItem::getId).collect(Collectors.toList())
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+23
-9
@@ -95,21 +95,26 @@ public class WiredEffectToggleFurni extends InteractionWiredEffect {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void serializeWiredData(ServerMessage message, Room room) {
|
public void serializeWiredData(ServerMessage message, Room room) {
|
||||||
THashSet<HabboItem> items = new THashSet<>();
|
// Snapshot items to avoid concurrent modification with execute() on room cycle thread
|
||||||
|
List<HabboItem> snapshot = new ArrayList<>(this.items);
|
||||||
|
|
||||||
for (HabboItem item : this.items) {
|
List<HabboItem> invalidItems = new ArrayList<>();
|
||||||
|
for (HabboItem item : snapshot) {
|
||||||
if (item.getRoomId() != this.getRoomId() || Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null)
|
if (item.getRoomId() != this.getRoomId() || Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null)
|
||||||
items.add(item);
|
invalidItems.add(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (HabboItem item : items) {
|
for (HabboItem item : invalidItems) {
|
||||||
this.items.remove(item);
|
this.items.remove(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<HabboItem> validItems = new ArrayList<>(snapshot);
|
||||||
|
validItems.removeAll(invalidItems);
|
||||||
|
|
||||||
message.appendBoolean(false);
|
message.appendBoolean(false);
|
||||||
message.appendInt(WiredManager.MAXIMUM_FURNI_SELECTION);
|
message.appendInt(WiredManager.MAXIMUM_FURNI_SELECTION);
|
||||||
message.appendInt(this.items.size());
|
message.appendInt(validItems.size());
|
||||||
for (HabboItem item : this.items) {
|
for (HabboItem item : validItems) {
|
||||||
message.appendInt(item.getId());
|
message.appendInt(item.getId());
|
||||||
}
|
}
|
||||||
message.appendInt(this.getBaseItem().getSpriteId());
|
message.appendInt(this.getBaseItem().getSpriteId());
|
||||||
@@ -177,8 +182,15 @@ public class WiredEffectToggleFurni extends InteractionWiredEffect {
|
|||||||
Room room = ctx.room();
|
Room room = ctx.room();
|
||||||
Habbo habbo = ctx.actor().map(unit -> room.getHabbo(unit)).orElse(null);
|
Habbo habbo = ctx.actor().map(unit -> room.getHabbo(unit)).orElse(null);
|
||||||
|
|
||||||
|
// Use selector targets if a selector has modified them, otherwise use manually picked items.
|
||||||
|
// Snapshot this.items into a new list to avoid undefined behavior from concurrent
|
||||||
|
// THashSet access (serializeWiredData can modify items from the network thread).
|
||||||
|
Iterable<HabboItem> effectiveItems = ctx.targets().isItemsModifiedBySelector()
|
||||||
|
? ctx.targets().items()
|
||||||
|
: new ArrayList<>(this.items);
|
||||||
|
|
||||||
THashSet<HabboItem> itemsToRemove = new THashSet<>();
|
THashSet<HabboItem> itemsToRemove = new THashSet<>();
|
||||||
for (HabboItem item : this.items) {
|
for (HabboItem item : effectiveItems) {
|
||||||
if (item == null || item.getRoomId() == 0 || FORBIDDEN_TYPES.stream().anyMatch(a -> a.isAssignableFrom(item.getClass()))) {
|
if (item == null || item.getRoomId() == 0 || FORBIDDEN_TYPES.stream().anyMatch(a -> a.isAssignableFrom(item.getClass()))) {
|
||||||
itemsToRemove.add(item);
|
itemsToRemove.add(item);
|
||||||
continue;
|
continue;
|
||||||
@@ -201,7 +213,9 @@ public class WiredEffectToggleFurni extends InteractionWiredEffect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.items.removeAll(itemsToRemove);
|
if (!ctx.targets().isItemsModifiedBySelector()) {
|
||||||
|
this.items.removeAll(itemsToRemove);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
@@ -214,7 +228,7 @@ public class WiredEffectToggleFurni extends InteractionWiredEffect {
|
|||||||
public String getWiredData() {
|
public String getWiredData() {
|
||||||
return WiredManager.getGson().toJson(new JsonData(
|
return WiredManager.getGson().toJson(new JsonData(
|
||||||
this.getDelay(),
|
this.getDelay(),
|
||||||
this.items.stream().map(HabboItem::getId).collect(Collectors.toList())
|
new ArrayList<>(this.items).stream().map(HabboItem::getId).collect(Collectors.toList())
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+16
-7
@@ -92,9 +92,10 @@ public class WiredEffectToggleRandom extends InteractionWiredEffect {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void serializeWiredData(ServerMessage message, Room room) {
|
public void serializeWiredData(ServerMessage message, Room room) {
|
||||||
|
List<HabboItem> itemsSnapshot = new ArrayList<>(this.items);
|
||||||
THashSet<HabboItem> items = new THashSet<>();
|
THashSet<HabboItem> items = new THashSet<>();
|
||||||
|
|
||||||
for (HabboItem item : this.items) {
|
for (HabboItem item : itemsSnapshot) {
|
||||||
if (item.getRoomId() != this.getRoomId() || Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null)
|
if (item.getRoomId() != this.getRoomId() || Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null)
|
||||||
items.add(item);
|
items.add(item);
|
||||||
}
|
}
|
||||||
@@ -103,10 +104,11 @@ public class WiredEffectToggleRandom extends InteractionWiredEffect {
|
|||||||
this.items.remove(item);
|
this.items.remove(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
itemsSnapshot = new ArrayList<>(this.items);
|
||||||
message.appendBoolean(false);
|
message.appendBoolean(false);
|
||||||
message.appendInt(WiredManager.MAXIMUM_FURNI_SELECTION);
|
message.appendInt(WiredManager.MAXIMUM_FURNI_SELECTION);
|
||||||
message.appendInt(this.items.size());
|
message.appendInt(itemsSnapshot.size());
|
||||||
for (HabboItem item : this.items) {
|
for (HabboItem item : itemsSnapshot) {
|
||||||
message.appendInt(item.getId());
|
message.appendInt(item.getId());
|
||||||
}
|
}
|
||||||
message.appendInt(this.getBaseItem().getSpriteId());
|
message.appendInt(this.getBaseItem().getSpriteId());
|
||||||
@@ -172,11 +174,17 @@ public class WiredEffectToggleRandom extends InteractionWiredEffect {
|
|||||||
@Override
|
@Override
|
||||||
public void execute(WiredContext ctx) {
|
public void execute(WiredContext ctx) {
|
||||||
Room room = ctx.room();
|
Room room = ctx.room();
|
||||||
THashSet<HabboItem> items = this.items;
|
|
||||||
|
|
||||||
for (HabboItem item : items) {
|
// Use selector targets if a selector has modified them, otherwise use manually picked items
|
||||||
|
Iterable<HabboItem> effectiveItems = ctx.targets().isItemsModifiedBySelector()
|
||||||
|
? ctx.targets().items()
|
||||||
|
: new ArrayList<>(this.items);
|
||||||
|
|
||||||
|
for (HabboItem item : effectiveItems) {
|
||||||
if (item.getRoomId() == 0 || FORBIDDEN_TYPES.stream().anyMatch(a -> a.isAssignableFrom(item.getClass()))) {
|
if (item.getRoomId() == 0 || FORBIDDEN_TYPES.stream().anyMatch(a -> a.isAssignableFrom(item.getClass()))) {
|
||||||
this.items.remove(item);
|
if (!ctx.targets().isItemsModifiedBySelector()) {
|
||||||
|
this.items.remove(item);
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,9 +205,10 @@ public class WiredEffectToggleRandom extends InteractionWiredEffect {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getWiredData() {
|
public String getWiredData() {
|
||||||
|
List<HabboItem> itemsSnapshot = new ArrayList<>(this.items);
|
||||||
return WiredManager.getGson().toJson(new JsonData(
|
return WiredManager.getGson().toJson(new JsonData(
|
||||||
this.getDelay(),
|
this.getDelay(),
|
||||||
this.items.stream().map(HabboItem::getId).collect(Collectors.toList())
|
itemsSnapshot.stream().map(HabboItem::getId).collect(Collectors.toList())
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+13
-5
@@ -41,9 +41,10 @@ public class WiredEffectTriggerStacks extends InteractionWiredEffect {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void serializeWiredData(ServerMessage message, Room room) {
|
public void serializeWiredData(ServerMessage message, Room room) {
|
||||||
|
List<HabboItem> itemsSnapshot = new ArrayList<>(this.items);
|
||||||
THashSet<HabboItem> items = new THashSet<>();
|
THashSet<HabboItem> items = new THashSet<>();
|
||||||
|
|
||||||
for (HabboItem item : this.items) {
|
for (HabboItem item : itemsSnapshot) {
|
||||||
if (item.getRoomId() != this.getRoomId() || Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null)
|
if (item.getRoomId() != this.getRoomId() || Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId()).getHabboItem(item.getId()) == null)
|
||||||
items.add(item);
|
items.add(item);
|
||||||
}
|
}
|
||||||
@@ -51,10 +52,11 @@ public class WiredEffectTriggerStacks extends InteractionWiredEffect {
|
|||||||
for (HabboItem item : items) {
|
for (HabboItem item : items) {
|
||||||
this.items.remove(item);
|
this.items.remove(item);
|
||||||
}
|
}
|
||||||
|
itemsSnapshot = new ArrayList<>(this.items);
|
||||||
message.appendBoolean(false);
|
message.appendBoolean(false);
|
||||||
message.appendInt(WiredManager.MAXIMUM_FURNI_SELECTION);
|
message.appendInt(WiredManager.MAXIMUM_FURNI_SELECTION);
|
||||||
message.appendInt(this.items.size());
|
message.appendInt(itemsSnapshot.size());
|
||||||
for (HabboItem item : this.items) {
|
for (HabboItem item : itemsSnapshot) {
|
||||||
message.appendInt(item.getId());
|
message.appendInt(item.getId());
|
||||||
}
|
}
|
||||||
message.appendInt(this.getBaseItem().getSpriteId());
|
message.appendInt(this.getBaseItem().getSpriteId());
|
||||||
@@ -135,9 +137,14 @@ public class WiredEffectTriggerStacks extends InteractionWiredEffect {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use selector targets if a selector has modified them, otherwise use manually picked items
|
||||||
|
Iterable<HabboItem> effectiveItems = ctx.targets().isItemsModifiedBySelector()
|
||||||
|
? ctx.targets().items()
|
||||||
|
: new ArrayList<>(this.items);
|
||||||
|
|
||||||
THashSet<RoomTile> usedTiles = new THashSet<>();
|
THashSet<RoomTile> usedTiles = new THashSet<>();
|
||||||
|
|
||||||
for (HabboItem item : this.items) {
|
for (HabboItem item : effectiveItems) {
|
||||||
if (item == null) continue;
|
if (item == null) continue;
|
||||||
|
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
@@ -169,9 +176,10 @@ public class WiredEffectTriggerStacks extends InteractionWiredEffect {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getWiredData() {
|
public String getWiredData() {
|
||||||
|
List<HabboItem> itemsSnapshot = new ArrayList<>(this.items);
|
||||||
return WiredManager.getGson().toJson(new JsonData(
|
return WiredManager.getGson().toJson(new JsonData(
|
||||||
this.getDelay(),
|
this.getDelay(),
|
||||||
this.items.stream().map(HabboItem::getId).collect(Collectors.toList())
|
itemsSnapshot.stream().map(HabboItem::getId).collect(Collectors.toList())
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
-2
@@ -2,6 +2,7 @@ package com.eu.habbo.habbohotel.items.interactions.wired.selector;
|
|||||||
|
|
||||||
import com.eu.habbo.habbohotel.gameclients.GameClient;
|
import com.eu.habbo.habbohotel.gameclients.GameClient;
|
||||||
import com.eu.habbo.habbohotel.items.Item;
|
import com.eu.habbo.habbohotel.items.Item;
|
||||||
|
import com.eu.habbo.habbohotel.items.interactions.InteractionWired;
|
||||||
import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect;
|
import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect;
|
||||||
import com.eu.habbo.habbohotel.items.interactions.wired.WiredSettings;
|
import com.eu.habbo.habbohotel.items.interactions.wired.WiredSettings;
|
||||||
import com.eu.habbo.habbohotel.rooms.Room;
|
import com.eu.habbo.habbohotel.rooms.Room;
|
||||||
@@ -42,7 +43,9 @@ public class WiredEffectFurniArea extends InteractionWiredEffect {
|
|||||||
if (room == null || areaWidth <= 0 || areaHeight <= 0) return;
|
if (room == null || areaWidth <= 0 || areaHeight <= 0) return;
|
||||||
|
|
||||||
List<HabboItem> furniInArea = getFurniInArea(room);
|
List<HabboItem> furniInArea = getFurniInArea(room);
|
||||||
ctx.targets().setItems(furniInArea);
|
if (!furniInArea.isEmpty()) {
|
||||||
|
ctx.targets().setItems(furniInArea);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<HabboItem> getFurniInArea(Room room) {
|
private List<HabboItem> getFurniInArea(Room room) {
|
||||||
@@ -54,7 +57,7 @@ public class WiredEffectFurniArea extends InteractionWiredEffect {
|
|||||||
for (int x = rootX; x <= maxX; x++) {
|
for (int x = rootX; x <= maxX; x++) {
|
||||||
for (int y = rootY; y <= maxY; y++) {
|
for (int y = rootY; y <= maxY; y++) {
|
||||||
for (HabboItem item : room.getItemsAt(x, y)) {
|
for (HabboItem item : room.getItemsAt(x, y)) {
|
||||||
if (item != null && !result.contains(item)) {
|
if (item != null && !(item instanceof InteractionWired) && !result.contains(item)) {
|
||||||
result.add(item);
|
result.add(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -85,6 +88,11 @@ public class WiredEffectFurniArea extends InteractionWiredEffect {
|
|||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSelector() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getWiredData() {
|
public String getWiredData() {
|
||||||
return WiredManager.getGson().toJson(new JsonData(rootX, rootY, areaWidth, areaHeight, getDelay()));
|
return WiredManager.getGson().toJson(new JsonData(rootX, rootY, areaWidth, areaHeight, getDelay()));
|
||||||
|
|||||||
+14
-3
@@ -2,6 +2,7 @@ package com.eu.habbo.habbohotel.items.interactions.wired.selector;
|
|||||||
|
|
||||||
import com.eu.habbo.habbohotel.gameclients.GameClient;
|
import com.eu.habbo.habbohotel.gameclients.GameClient;
|
||||||
import com.eu.habbo.habbohotel.items.Item;
|
import com.eu.habbo.habbohotel.items.Item;
|
||||||
|
import com.eu.habbo.habbohotel.items.interactions.InteractionWired;
|
||||||
import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect;
|
import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect;
|
||||||
import com.eu.habbo.habbohotel.items.interactions.wired.WiredSettings;
|
import com.eu.habbo.habbohotel.items.interactions.wired.WiredSettings;
|
||||||
import com.eu.habbo.habbohotel.rooms.Room;
|
import com.eu.habbo.habbohotel.rooms.Room;
|
||||||
@@ -60,6 +61,7 @@ public class WiredEffectFurniByType extends InteractionWiredEffect {
|
|||||||
|
|
||||||
Set<HabboItem> result = new LinkedHashSet<>();
|
Set<HabboItem> result = new LinkedHashSet<>();
|
||||||
room.getFloorItems().forEach(item -> {
|
room.getFloorItems().forEach(item -> {
|
||||||
|
if (item instanceof InteractionWired) return;
|
||||||
String key = matchState
|
String key = matchState
|
||||||
? item.getBaseItem().getId() + ":" + item.getExtradata()
|
? item.getBaseItem().getId() + ":" + item.getExtradata()
|
||||||
: String.valueOf(item.getBaseItem().getId());
|
: String.valueOf(item.getBaseItem().getId());
|
||||||
@@ -74,10 +76,14 @@ public class WiredEffectFurniByType extends InteractionWiredEffect {
|
|||||||
|
|
||||||
if (invert) {
|
if (invert) {
|
||||||
Set<HabboItem> all = new LinkedHashSet<>();
|
Set<HabboItem> all = new LinkedHashSet<>();
|
||||||
room.getFloorItems().forEach(all::add);
|
room.getFloorItems().forEach(item -> {
|
||||||
|
if (!(item instanceof InteractionWired)) all.add(item);
|
||||||
|
});
|
||||||
all.removeAll(result);
|
all.removeAll(result);
|
||||||
ctx.targets().setItems(all);
|
if (!all.isEmpty()) {
|
||||||
} else {
|
ctx.targets().setItems(all);
|
||||||
|
}
|
||||||
|
} else if (!result.isEmpty()) {
|
||||||
ctx.targets().setItems(result);
|
ctx.targets().setItems(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -160,6 +166,11 @@ public class WiredEffectFurniByType extends InteractionWiredEffect {
|
|||||||
@Override
|
@Override
|
||||||
public WiredEffectType getType() { return type; }
|
public WiredEffectType getType() { return type; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSelector() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getWiredData() {
|
public String getWiredData() {
|
||||||
return WiredManager.getGson().toJson(
|
return WiredManager.getGson().toJson(
|
||||||
|
|||||||
+45
-2
@@ -2,6 +2,7 @@ package com.eu.habbo.habbohotel.items.interactions.wired.selector;
|
|||||||
|
|
||||||
import com.eu.habbo.habbohotel.gameclients.GameClient;
|
import com.eu.habbo.habbohotel.gameclients.GameClient;
|
||||||
import com.eu.habbo.habbohotel.items.Item;
|
import com.eu.habbo.habbohotel.items.Item;
|
||||||
|
import com.eu.habbo.habbohotel.items.interactions.InteractionWired;
|
||||||
import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect;
|
import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect;
|
||||||
import com.eu.habbo.habbohotel.items.interactions.wired.WiredSettings;
|
import com.eu.habbo.habbohotel.items.interactions.wired.WiredSettings;
|
||||||
import com.eu.habbo.habbohotel.rooms.Room;
|
import com.eu.habbo.habbohotel.rooms.Room;
|
||||||
@@ -12,6 +13,8 @@ import com.eu.habbo.habbohotel.wired.core.WiredContext;
|
|||||||
import com.eu.habbo.habbohotel.wired.core.WiredManager;
|
import com.eu.habbo.habbohotel.wired.core.WiredManager;
|
||||||
import com.eu.habbo.messages.ServerMessage;
|
import com.eu.habbo.messages.ServerMessage;
|
||||||
import com.eu.habbo.messages.incoming.wired.WiredSaveException;
|
import com.eu.habbo.messages.incoming.wired.WiredSaveException;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
@@ -19,6 +22,7 @@ import java.util.*;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class WiredEffectFurniNeighborhood extends InteractionWiredEffect {
|
public class WiredEffectFurniNeighborhood extends InteractionWiredEffect {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(WiredEffectFurniNeighborhood.class);
|
||||||
|
|
||||||
public static final WiredEffectType type = WiredEffectType.FURNI_NEIGHBORHOOD_SELECTOR;
|
public static final WiredEffectType type = WiredEffectType.FURNI_NEIGHBORHOOD_SELECTOR;
|
||||||
|
|
||||||
@@ -58,16 +62,30 @@ public class WiredEffectFurniNeighborhood extends InteractionWiredEffect {
|
|||||||
List<int[]> sourcePositions = resolveSourcePositions(ctx, room);
|
List<int[]> sourcePositions = resolveSourcePositions(ctx, room);
|
||||||
if (sourcePositions.isEmpty()) return;
|
if (sourcePositions.isEmpty()) return;
|
||||||
|
|
||||||
|
int totalRaw = 0;
|
||||||
|
int wiredSkipped = 0;
|
||||||
Set<HabboItem> result = new LinkedHashSet<>();
|
Set<HabboItem> result = new LinkedHashSet<>();
|
||||||
for (int[] src : sourcePositions) {
|
for (int[] src : sourcePositions) {
|
||||||
|
LOGGER.info("[FurniNeighborhood] Source: ({},{}), offsets: {}", src[0], src[1], tileOffsets.size());
|
||||||
for (int[] offset : tileOffsets) {
|
for (int[] offset : tileOffsets) {
|
||||||
int tx = src[0] + offset[0];
|
int tx = src[0] + offset[0];
|
||||||
int ty = src[1] + offset[1];
|
int ty = src[1] + offset[1];
|
||||||
for (HabboItem item : room.getItemsAt(tx, ty)) {
|
for (HabboItem item : room.getItemsAt(tx, ty)) {
|
||||||
if (item != null) result.add(item);
|
if (item == null) continue;
|
||||||
|
totalRaw++;
|
||||||
|
if (item instanceof InteractionWired) {
|
||||||
|
wiredSkipped++;
|
||||||
|
LOGGER.info("[FurniNeighborhood] SKIP wired item {} ({}) at ({},{})",
|
||||||
|
item.getId(), item.getClass().getSimpleName(), tx, ty);
|
||||||
|
} else {
|
||||||
|
result.add(item);
|
||||||
|
LOGGER.info("[FurniNeighborhood] KEEP item {} ({}) at ({},{})",
|
||||||
|
item.getId(), item.getClass().getSimpleName(), tx, ty);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
LOGGER.info("[FurniNeighborhood] Raw={}, wiredSkipped={}, kept={}", totalRaw, wiredSkipped, result.size());
|
||||||
|
|
||||||
if (filterExisting) {
|
if (filterExisting) {
|
||||||
result.retainAll(ctx.targets().items());
|
result.retainAll(ctx.targets().items());
|
||||||
@@ -75,17 +93,29 @@ public class WiredEffectFurniNeighborhood extends InteractionWiredEffect {
|
|||||||
|
|
||||||
if (invert) {
|
if (invert) {
|
||||||
Set<HabboItem> all = new LinkedHashSet<>();
|
Set<HabboItem> all = new LinkedHashSet<>();
|
||||||
room.getFloorItems().forEach(all::add);
|
room.getFloorItems().forEach(item -> {
|
||||||
|
if (!(item instanceof InteractionWired)) all.add(item);
|
||||||
|
});
|
||||||
all.removeAll(result);
|
all.removeAll(result);
|
||||||
result = all;
|
result = all;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Always set the selector result — even if empty.
|
||||||
|
// An empty result means no items matched the neighborhood, so downstream
|
||||||
|
// effects should target nothing rather than falling back to the original targets.
|
||||||
ctx.targets().setItems(result);
|
ctx.targets().setItems(result);
|
||||||
|
LOGGER.info("[FurniNeighborhood] Set {} items as targets", result.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<int[]> resolveSourcePositions(WiredContext ctx, Room room) {
|
private List<int[]> resolveSourcePositions(WiredContext ctx, Room room) {
|
||||||
|
|
||||||
if (isUserGroup(sourceType)) {
|
if (isUserGroup(sourceType)) {
|
||||||
|
// Prefer the event tile for user-based sources because during walk-on/walk-off
|
||||||
|
// events the user's position (getX/getY) hasn't been updated yet (stale position).
|
||||||
|
// The event tile correctly represents where the triggering action occurred.
|
||||||
|
if (ctx.tile().isPresent()) {
|
||||||
|
return Collections.singletonList(new int[]{ ctx.tile().get().x, ctx.tile().get().y });
|
||||||
|
}
|
||||||
List<int[]> positions = ctx.targets().users().stream()
|
List<int[]> positions = ctx.targets().users().stream()
|
||||||
.map(u -> new int[]{ u.getX(), u.getY() })
|
.map(u -> new int[]{ u.getX(), u.getY() })
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
@@ -149,6 +179,14 @@ public class WiredEffectFurniNeighborhood extends InteractionWiredEffect {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.setDelay(settings.getDelay());
|
this.setDelay(settings.getDelay());
|
||||||
|
|
||||||
|
LOGGER.info("[FurniNeighborhood] saveData: sourceType={}, filterExisting={}, invert={}, offsets={}, pickedFurniIds={}",
|
||||||
|
sourceType, filterExisting, invert, tileOffsets.size(), pickedFurniIds);
|
||||||
|
for (int[] o : tileOffsets) {
|
||||||
|
LOGGER.info("[FurniNeighborhood] offset: ({}, {})", o[0], o[1]);
|
||||||
|
}
|
||||||
|
LOGGER.info("[FurniNeighborhood] raw intParams (len={}): {}", params.length, java.util.Arrays.toString(params));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,6 +228,11 @@ public class WiredEffectFurniNeighborhood extends InteractionWiredEffect {
|
|||||||
@Override
|
@Override
|
||||||
public WiredEffectType getType() { return type; }
|
public WiredEffectType getType() { return type; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSelector() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getWiredData() {
|
public String getWiredData() {
|
||||||
return WiredManager.getGson().toJson(
|
return WiredManager.getGson().toJson(
|
||||||
|
|||||||
+3
-1
@@ -64,7 +64,9 @@ public class WiredEffectUsersArea extends InteractionWiredEffect {
|
|||||||
usersInArea.retainAll(ctx.targets().users());
|
usersInArea.retainAll(ctx.targets().users());
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.targets().setUsers(usersInArea);
|
if (!usersInArea.isEmpty()) {
|
||||||
|
ctx.targets().setUsers(usersInArea);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+303
@@ -0,0 +1,303 @@
|
|||||||
|
package com.eu.habbo.habbohotel.items.interactions.wired.selector;
|
||||||
|
|
||||||
|
import com.eu.habbo.habbohotel.gameclients.GameClient;
|
||||||
|
import com.eu.habbo.habbohotel.items.Item;
|
||||||
|
import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect;
|
||||||
|
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.rooms.RoomUnitType;
|
||||||
|
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.messages.ServerMessage;
|
||||||
|
import com.eu.habbo.messages.incoming.wired.WiredSaveException;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class WiredEffectUsersNeighborhood extends InteractionWiredEffect {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(WiredEffectUsersNeighborhood.class);
|
||||||
|
|
||||||
|
public static final WiredEffectType type = WiredEffectType.USERS_NEIGHBORHOOD_SELECTOR;
|
||||||
|
|
||||||
|
private static final int SOURCE_USER_TRIGGER = 0;
|
||||||
|
private static final int SOURCE_USER_SIGNAL = 1;
|
||||||
|
private static final int SOURCE_USER_CLICKED = 2;
|
||||||
|
private static final int SOURCE_FURNI_TRIGGER = 3;
|
||||||
|
private static final int SOURCE_FURNI_PICKED = 4;
|
||||||
|
private static final int SOURCE_FURNI_SIGNAL = 5;
|
||||||
|
|
||||||
|
private static boolean isUserGroup(int src) { return src <= SOURCE_USER_CLICKED; }
|
||||||
|
private static boolean isFurniGroup(int src) { return src >= SOURCE_FURNI_TRIGGER; }
|
||||||
|
|
||||||
|
private static final int MAX_PICKED_FURNI = 20;
|
||||||
|
private static final int MAX_TILE_OFFSETS = 64;
|
||||||
|
|
||||||
|
private int sourceType = SOURCE_USER_TRIGGER;
|
||||||
|
private boolean filterExisting = false;
|
||||||
|
private boolean invert = false;
|
||||||
|
private boolean excludeBots = false;
|
||||||
|
private boolean excludePets = false;
|
||||||
|
private List<int[]> tileOffsets = new ArrayList<>();
|
||||||
|
private List<Integer> pickedFurniIds = new ArrayList<>();
|
||||||
|
|
||||||
|
public WiredEffectUsersNeighborhood(ResultSet set, Item baseItem) throws SQLException {
|
||||||
|
super(set, baseItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WiredEffectUsersNeighborhood(int id, int userId, Item item, String extradata,
|
||||||
|
int limitedStack, int limitedSells) {
|
||||||
|
super(id, userId, item, extradata, limitedStack, limitedSells);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(WiredContext ctx) {
|
||||||
|
Room room = ctx.room();
|
||||||
|
if (room == null || tileOffsets.isEmpty()) {
|
||||||
|
LOGGER.debug("[Neighborhood] Skipping: room={} tileOffsets.size={}", room != null ? room.getId() : "null", tileOffsets.size());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<int[]> sourcePositions = resolveSourcePositions(ctx, room);
|
||||||
|
if (sourcePositions.isEmpty()) {
|
||||||
|
LOGGER.debug("[Neighborhood] No source positions resolved (sourceType={})", sourceType);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGGER.debug("[Neighborhood] sourceType={} sourcePositions={} tileOffsets={} filterExisting={} invert={}",
|
||||||
|
sourceType,
|
||||||
|
sourcePositions.stream().map(p -> p[0] + "," + p[1]).collect(Collectors.joining(";")),
|
||||||
|
tileOffsets.stream().map(o -> o[0] + "," + o[1]).collect(Collectors.joining(";")),
|
||||||
|
filterExisting, invert);
|
||||||
|
|
||||||
|
// Apply tile offsets relative to each source position.
|
||||||
|
// The offsets define a neighborhood pattern around the source furni/user.
|
||||||
|
Set<String> targetTiles = new HashSet<>();
|
||||||
|
for (int[] src : sourcePositions) {
|
||||||
|
for (int[] offset : tileOffsets) {
|
||||||
|
int tx = src[0] + offset[0];
|
||||||
|
int ty = src[1] + offset[1];
|
||||||
|
targetTiles.add(tx + "," + ty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGGER.debug("[Neighborhood] Target tiles: {}", targetTiles);
|
||||||
|
|
||||||
|
List<RoomUnit> result = new ArrayList<>();
|
||||||
|
for (RoomUnit unit : room.getRoomUnits()) {
|
||||||
|
if (excludeBots && unit.getRoomUnitType() == RoomUnitType.BOT) continue;
|
||||||
|
if (excludePets && unit.getRoomUnitType() == RoomUnitType.PET) continue;
|
||||||
|
|
||||||
|
String pos = unit.getX() + "," + unit.getY();
|
||||||
|
boolean onTile = targetTiles.contains(pos);
|
||||||
|
|
||||||
|
LOGGER.debug("[Neighborhood] Unit id={} type={} pos={} onTile={}", unit.getId(), unit.getRoomUnitType(), pos, onTile);
|
||||||
|
|
||||||
|
if (invert ? !onTile : onTile) {
|
||||||
|
result.add(unit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filterExisting) {
|
||||||
|
result.retainAll(ctx.targets().users());
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGGER.debug("[Neighborhood] Result: {} users selected", result.size());
|
||||||
|
|
||||||
|
// Always set the selector result — even if empty.
|
||||||
|
// An empty result means no users matched the neighborhood, so downstream
|
||||||
|
// effects (e.g. kick) should target nobody rather than falling back to the
|
||||||
|
// triggering user.
|
||||||
|
ctx.targets().setUsers(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<int[]> resolveSourcePositions(WiredContext ctx, Room room) {
|
||||||
|
|
||||||
|
if (isUserGroup(sourceType)) {
|
||||||
|
// Prefer the event tile for user-based sources because during walk-on/walk-off
|
||||||
|
// events the user's position (getX/getY) hasn't been updated yet (stale position).
|
||||||
|
// The event tile correctly represents where the triggering action occurred.
|
||||||
|
if (ctx.tile().isPresent()) {
|
||||||
|
return Collections.singletonList(new int[]{ ctx.tile().get().x, ctx.tile().get().y });
|
||||||
|
}
|
||||||
|
List<int[]> positions = ctx.targets().users().stream()
|
||||||
|
.map(u -> new int[]{ u.getX(), u.getY() })
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
if (positions.isEmpty()) {
|
||||||
|
ctx.actor().ifPresent(a -> positions.add(new int[]{ a.getX(), a.getY() }));
|
||||||
|
}
|
||||||
|
return positions;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (sourceType) {
|
||||||
|
case SOURCE_FURNI_TRIGGER: {
|
||||||
|
return ctx.sourceItem()
|
||||||
|
.map(i -> Collections.singletonList(new int[]{ i.getX(), i.getY() }))
|
||||||
|
.orElse(Collections.emptyList());
|
||||||
|
}
|
||||||
|
case SOURCE_FURNI_PICKED: {
|
||||||
|
return pickedFurniIds.stream()
|
||||||
|
.map(room::getHabboItem)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.map(i -> new int[]{ i.getX(), i.getY() })
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
case SOURCE_FURNI_SIGNAL: {
|
||||||
|
return ctx.targets().items().stream()
|
||||||
|
.map(i -> new int[]{ i.getX(), i.getY() })
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean saveData(WiredSettings settings, GameClient gameClient) throws WiredSaveException {
|
||||||
|
int[] params = settings.getIntParams();
|
||||||
|
if (params == null || params.length < 1) {
|
||||||
|
throw new WiredSaveException("wf_slc_users_neighborhood: intParams must have at least 1 element");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.sourceType = params[0];
|
||||||
|
this.filterExisting = params.length > 1 && params[1] == 1;
|
||||||
|
this.invert = params.length > 2 && params[2] == 1;
|
||||||
|
this.excludeBots = params.length > 3 && params[3] == 1;
|
||||||
|
this.excludePets = params.length > 4 && params[4] == 1;
|
||||||
|
|
||||||
|
this.tileOffsets = new ArrayList<>();
|
||||||
|
if (params.length > 5) {
|
||||||
|
int n = params[5];
|
||||||
|
for (int i = 0; i < n && i < MAX_TILE_OFFSETS; i++) {
|
||||||
|
int xi = 6 + i * 2;
|
||||||
|
if (xi + 1 < params.length) {
|
||||||
|
tileOffsets.add(new int[]{ params[xi], params[xi + 1] });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.pickedFurniIds = new ArrayList<>();
|
||||||
|
if (this.sourceType == SOURCE_FURNI_PICKED && settings.getFurniIds() != null) {
|
||||||
|
for (int id : settings.getFurniIds()) {
|
||||||
|
if (pickedFurniIds.size() >= MAX_PICKED_FURNI) break;
|
||||||
|
pickedFurniIds.add(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setDelay(settings.getDelay());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void serializeWiredData(ServerMessage message, Room room) {
|
||||||
|
boolean pickMode = (sourceType == SOURCE_FURNI_PICKED);
|
||||||
|
|
||||||
|
message.appendBoolean(pickMode);
|
||||||
|
message.appendInt(pickMode ? MAX_PICKED_FURNI : 0);
|
||||||
|
|
||||||
|
if (pickMode && !pickedFurniIds.isEmpty()) {
|
||||||
|
message.appendInt(pickedFurniIds.size());
|
||||||
|
pickedFurniIds.forEach(message::appendInt);
|
||||||
|
} else {
|
||||||
|
message.appendInt(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
message.appendInt(this.getBaseItem().getSpriteId());
|
||||||
|
message.appendInt(this.getId());
|
||||||
|
message.appendString("");
|
||||||
|
|
||||||
|
int paramCount = 6 + tileOffsets.size() * 2;
|
||||||
|
message.appendInt(paramCount);
|
||||||
|
message.appendInt(sourceType);
|
||||||
|
message.appendInt(filterExisting ? 1 : 0);
|
||||||
|
message.appendInt(invert ? 1 : 0);
|
||||||
|
message.appendInt(excludeBots ? 1 : 0);
|
||||||
|
message.appendInt(excludePets ? 1 : 0);
|
||||||
|
message.appendInt(tileOffsets.size());
|
||||||
|
for (int[] offset : tileOffsets) {
|
||||||
|
message.appendInt(offset[0]);
|
||||||
|
message.appendInt(offset[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
message.appendInt(0);
|
||||||
|
message.appendInt(this.getType().code);
|
||||||
|
message.appendInt(this.getDelay());
|
||||||
|
message.appendInt(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WiredEffectType getType() { return type; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSelector() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getWiredData() {
|
||||||
|
return WiredManager.getGson().toJson(
|
||||||
|
new JsonData(sourceType, filterExisting, invert, excludeBots, excludePets, tileOffsets, pickedFurniIds, getDelay()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void loadWiredData(ResultSet set, Room room) throws SQLException {
|
||||||
|
String wiredData = set.getString("wired_data");
|
||||||
|
if (wiredData != null && wiredData.startsWith("{")) {
|
||||||
|
JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
|
||||||
|
this.sourceType = data.sourceType;
|
||||||
|
this.filterExisting = data.filterExisting;
|
||||||
|
this.invert = data.invert;
|
||||||
|
this.excludeBots = data.excludeBots;
|
||||||
|
this.excludePets = data.excludePets;
|
||||||
|
this.tileOffsets = data.tileOffsets != null ? data.tileOffsets : new ArrayList<>();
|
||||||
|
this.pickedFurniIds = data.pickedFurniIds != null ? data.pickedFurniIds : new ArrayList<>();
|
||||||
|
this.setDelay(data.delay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPickUp() {
|
||||||
|
this.sourceType = SOURCE_USER_TRIGGER;
|
||||||
|
this.filterExisting = false;
|
||||||
|
this.invert = false;
|
||||||
|
this.excludeBots = false;
|
||||||
|
this.excludePets = false;
|
||||||
|
this.tileOffsets = new ArrayList<>();
|
||||||
|
this.pickedFurniIds = new ArrayList<>();
|
||||||
|
this.setDelay(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) { return false; }
|
||||||
|
|
||||||
|
static class JsonData {
|
||||||
|
int sourceType;
|
||||||
|
boolean filterExisting;
|
||||||
|
boolean invert;
|
||||||
|
boolean excludeBots;
|
||||||
|
boolean excludePets;
|
||||||
|
List<int[]> tileOffsets;
|
||||||
|
List<Integer> pickedFurniIds;
|
||||||
|
int delay;
|
||||||
|
|
||||||
|
JsonData(int sourceType, boolean filterExisting, boolean invert,
|
||||||
|
boolean excludeBots, boolean excludePets,
|
||||||
|
List<int[]> tileOffsets, List<Integer> pickedFurniIds, int delay) {
|
||||||
|
this.sourceType = sourceType;
|
||||||
|
this.filterExisting = filterExisting;
|
||||||
|
this.invert = invert;
|
||||||
|
this.excludeBots = excludeBots;
|
||||||
|
this.excludePets = excludePets;
|
||||||
|
this.tileOffsets = tileOffsets;
|
||||||
|
this.pickedFurniIds = pickedFurniIds;
|
||||||
|
this.delay = delay;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+15
-4
@@ -123,13 +123,24 @@ public class WiredTriggerBotReachedFurni extends InteractionWiredTrigger {
|
|||||||
|
|
||||||
// Get the furniture item the bot walked onto
|
// Get the furniture item the bot walked onto
|
||||||
HabboItem sourceItem = event.getSourceItem().orElse(null);
|
HabboItem sourceItem = event.getSourceItem().orElse(null);
|
||||||
if (sourceItem == null || roomUnit == null) {
|
if (sourceItem == null || roomUnit == null || room == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if this furniture is in our monitored list AND the actor is the correct bot
|
boolean isCorrectBot = room.getBots(this.botName).stream().anyMatch(bot -> bot.getRoomUnit() == roomUnit);
|
||||||
return this.items.contains(sourceItem) &&
|
if (!isCorrectBot) {
|
||||||
room.getBots(this.botName).stream().anyMatch(bot -> bot.getRoomUnit() == roomUnit);
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.items.contains(sourceItem)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
for (HabboItem item : room.getItemsAt(sourceItem.getX(), sourceItem.getY())) {
|
||||||
|
if (this.items.contains(item)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
|
|||||||
+16
-2
@@ -36,9 +36,23 @@ public class WiredTriggerHabboWalkOffFurni extends InteractionWiredTrigger {
|
|||||||
@Override
|
@Override
|
||||||
public boolean matches(HabboItem triggerItem, WiredEvent event) {
|
public boolean matches(HabboItem triggerItem, WiredEvent event) {
|
||||||
HabboItem sourceItem = event.getSourceItem().orElse(null);
|
HabboItem sourceItem = event.getSourceItem().orElse(null);
|
||||||
if (sourceItem != null) {
|
if (sourceItem == null) {
|
||||||
return this.items.contains(sourceItem);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.items.contains(sourceItem)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Room room = event.getRoom();
|
||||||
|
if (room != null) {
|
||||||
|
for (HabboItem item : room.getItemsAt(sourceItem.getX(), sourceItem.getY())) {
|
||||||
|
if (this.items.contains(item)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+16
-2
@@ -36,9 +36,23 @@ public class WiredTriggerHabboWalkOnFurni extends InteractionWiredTrigger {
|
|||||||
@Override
|
@Override
|
||||||
public boolean matches(HabboItem triggerItem, WiredEvent event) {
|
public boolean matches(HabboItem triggerItem, WiredEvent event) {
|
||||||
HabboItem sourceItem = event.getSourceItem().orElse(null);
|
HabboItem sourceItem = event.getSourceItem().orElse(null);
|
||||||
if (sourceItem != null) {
|
if (sourceItem == null) {
|
||||||
return this.items.contains(sourceItem);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.items.contains(sourceItem)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Room room = event.getRoom();
|
||||||
|
if (room != null) {
|
||||||
|
for (HabboItem item : room.getItemsAt(sourceItem.getX(), sourceItem.getY())) {
|
||||||
|
if (this.items.contains(item)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,8 @@ public enum WiredEffectType {
|
|||||||
FURNI_AREA_SELECTOR(28),
|
FURNI_AREA_SELECTOR(28),
|
||||||
FURNI_NEIGHBORHOOD_SELECTOR(29),
|
FURNI_NEIGHBORHOOD_SELECTOR(29),
|
||||||
FURNI_BYTYPE_SELECTOR(30),
|
FURNI_BYTYPE_SELECTOR(30),
|
||||||
USERS_AREA_SELECTOR(31);
|
USERS_AREA_SELECTOR(31),
|
||||||
|
USERS_NEIGHBORHOOD_SELECTOR(32);
|
||||||
|
|
||||||
public final int code;
|
public final int code;
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ public final class WiredTargets {
|
|||||||
|
|
||||||
private final Set<RoomUnit> users = new LinkedHashSet<>();
|
private final Set<RoomUnit> users = new LinkedHashSet<>();
|
||||||
private final Set<HabboItem> items = new LinkedHashSet<>();
|
private final Set<HabboItem> items = new LinkedHashSet<>();
|
||||||
|
private boolean itemsModifiedBySelector = false;
|
||||||
|
private boolean usersModifiedBySelector = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all targeted users (read-only view).
|
* Get all targeted users (read-only view).
|
||||||
@@ -62,6 +64,24 @@ public final class WiredTargets {
|
|||||||
return !items.isEmpty();
|
return !items.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if item targets were explicitly set by a selector.
|
||||||
|
* Effects should use this to determine whether to use selector targets
|
||||||
|
* instead of their own manually configured items.
|
||||||
|
* @return true if a selector has called setItems()
|
||||||
|
*/
|
||||||
|
public boolean isItemsModifiedBySelector() {
|
||||||
|
return itemsModifiedBySelector;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if user targets were explicitly set by a selector.
|
||||||
|
* @return true if a selector has called setUsers()
|
||||||
|
*/
|
||||||
|
public boolean isUsersModifiedBySelector() {
|
||||||
|
return usersModifiedBySelector;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if there are any targets at all.
|
* Check if there are any targets at all.
|
||||||
* @return true if there are users or items
|
* @return true if there are users or items
|
||||||
@@ -118,6 +138,7 @@ public final class WiredTargets {
|
|||||||
*/
|
*/
|
||||||
public void setUsers(Iterable<RoomUnit> newUsers) {
|
public void setUsers(Iterable<RoomUnit> newUsers) {
|
||||||
users.clear();
|
users.clear();
|
||||||
|
usersModifiedBySelector = true;
|
||||||
if (newUsers != null) {
|
if (newUsers != null) {
|
||||||
for (RoomUnit u : newUsers) {
|
for (RoomUnit u : newUsers) {
|
||||||
if (u != null) users.add(u);
|
if (u != null) users.add(u);
|
||||||
@@ -131,6 +152,7 @@ public final class WiredTargets {
|
|||||||
*/
|
*/
|
||||||
public void setItems(Iterable<HabboItem> newItems) {
|
public void setItems(Iterable<HabboItem> newItems) {
|
||||||
items.clear();
|
items.clear();
|
||||||
|
itemsModifiedBySelector = true;
|
||||||
if (newItems != null) {
|
if (newItems != null) {
|
||||||
for (HabboItem i : newItems) {
|
for (HabboItem i : newItems) {
|
||||||
if (i != null) items.add(i);
|
if (i != null) items.add(i);
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user