Preserve signal origin actor context

This commit is contained in:
Lorenzune
2026-04-13 16:45:40 +02:00
parent 17e316e521
commit ae08d4b3f4
3 changed files with 332 additions and 7 deletions
@@ -103,30 +103,52 @@ public class WiredEffectSendSignal extends InteractionWiredEffect {
}
LOGGER.debug("[SendSignal] Resolved {} antenna(s), firing signals", resolvedAntennas.size());
RoomUnit triggeringUser = ctx.event().getOriginActor().orElseGet(() -> ctx.actor().orElse(null));
List<RoomUnit> forwardedUsers = WiredSourceUtil.resolveUsersRaw(ctx, this.userForward);
List<HabboItem> forwardedFurni = WiredSourceUtil.resolveItemsRaw(ctx, this.furniForward, this.forwardItems);
RoomUnit defaultUser = forwardedUsers.isEmpty() ? null : forwardedUsers.get(0);
Collection<RoomUnit> usersToSend = (signalPerUser && !forwardedUsers.isEmpty())
? forwardedUsers
: Collections.singletonList(defaultUser);
List<RoomUnit> usersToSend;
if (signalPerUser) {
LinkedHashMap<Integer, RoomUnit> mergedUsers = new LinkedHashMap<>();
if (triggeringUser != null) {
mergedUsers.put(triggeringUser.getId(), triggeringUser);
}
for (RoomUnit forwardedUser : forwardedUsers) {
if (forwardedUser == null) {
continue;
}
mergedUsers.put(forwardedUser.getId(), forwardedUser);
}
usersToSend = mergedUsers.isEmpty()
? Collections.singletonList(null)
: new ArrayList<>(mergedUsers.values());
} else {
usersToSend = Collections.singletonList(triggeringUser);
}
Collection<HabboItem> furniToSend = !forwardedFurni.isEmpty()
? forwardedFurni
: Collections.singletonList(null);
int nextDepth = currentDepth + 1;
int signalUserCount = signalPerUser
? (int) usersToSend.stream().filter(Objects::nonNull).count()
: (!forwardedUsers.isEmpty() ? forwardedUsers.size() : (triggeringUser != null ? 1 : 0));
for (RoomUnit user : usersToSend) {
for (HabboItem sourceItem : furniToSend) {
for (HabboItem antenna : resolvedAntennas) {
fireSignalAtAntenna(ctx, room, antenna, user, sourceItem, nextDepth);
fireSignalAtAntenna(ctx, room, antenna, user, triggeringUser, sourceItem, signalUserCount, nextDepth);
}
}
}
}
private void fireSignalAtAntenna(WiredContext ctx, Room room, HabboItem antenna, RoomUnit actor, HabboItem sourceItem, int depth) {
private void fireSignalAtAntenna(WiredContext ctx, Room room, HabboItem antenna, RoomUnit actor, RoomUnit originActor, HabboItem sourceItem, int signalUserCount, int depth) {
if (antenna == null) return;
RoomTile tile = room.getLayout().getTile(antenna.getX(), antenna.getY());
if (tile == null) return;
@@ -142,12 +164,13 @@ public class WiredEffectSendSignal extends InteractionWiredEffect {
.tile(tile)
.callStackDepth(depth)
.signalChannel(signalChannel)
.signalUserCount(actor != null ? 1 : 0)
.signalUserCount(signalUserCount)
.signalFurniCount(sourceItem != null ? 1 : 0)
.contextVariableScope(ctx.contextVariables())
.triggeredByEffect(true);
if (actor != null) builder.actor(actor);
if (originActor != null) builder.originActor(originActor);
if (sourceItem != null) builder.sourceItem(sourceItem);
boolean result = dispatchSignalEvent(builder.build());
@@ -163,6 +163,7 @@ public final class WiredEvent {
private final Type type;
private final Room room;
private final RoomUnit actor; // nullable - the user/bot that caused the event
private final RoomUnit originActor; // nullable - original user that started the chain, preserved across signals
private final HabboItem sourceItem; // nullable - the furniture involved
private final RoomTile tile; // nullable - the tile where event occurred
private final String text; // nullable - text for say triggers
@@ -191,6 +192,7 @@ public final class WiredEvent {
this.room = builder.room;
this.actor = builder.actor;
this.sourceItem = builder.sourceItem;
this.originActor = builder.originActor;
this.tile = builder.tile;
this.text = builder.text;
this.targetUnit = builder.targetUnit;
@@ -240,6 +242,17 @@ public final class WiredEvent {
return Optional.ofNullable(actor);
}
/**
* Get the original actor that started the current event chain.
* For signal events this can differ from {@link #getActor()} when the
* signal forwards users one-by-one but still needs to preserve who
* originally triggered the chain.
* @return optional containing the original actor, or empty if unavailable
*/
public Optional<RoomUnit> getOriginActor() {
return Optional.ofNullable(originActor);
}
/**
* Get the source item that was involved in this event.
* For example, the furniture that was clicked or stepped on.
@@ -407,6 +420,7 @@ public final class WiredEvent {
private final Type type;
private final Room room;
private RoomUnit actor;
private RoomUnit originActor;
private HabboItem sourceItem;
private RoomTile tile;
private String text;
@@ -447,6 +461,11 @@ public final class WiredEvent {
return this;
}
public Builder originActor(RoomUnit originActor) {
this.originActor = originActor;
return this;
}
/**
* Set the source item involved in this event.
* @param sourceItem the habbo item