🆙 Wired Highscore LONGESTTIME and Loop detection rollers
This commit is contained in:
parent
31fd5f2b31
commit
3332bc7f9c
2
Emulator/.idea/misc.xml
generated
2
Emulator/.idea/misc.xml
generated
@ -8,5 +8,5 @@
|
|||||||
</list>
|
</list>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="openjdk-21" project-jdk-type="JavaSDK" />
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_23" default="true" project-jdk-name="openjdk-23" project-jdk-type="JavaSDK" />
|
||||||
</project>
|
</project>
|
@ -26,14 +26,27 @@ public class SetSpeedCommand extends Command {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newSpeed < -1 || newSpeed > Emulator.getConfig().getInt("hotel.rollers.speed.maximum")) {
|
// First check against the config bounds
|
||||||
|
int configMax = Emulator.getConfig().getInt("hotel.rollers.speed.maximum");
|
||||||
|
if (newSpeed < -1 || newSpeed > configMax) {
|
||||||
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_setspeed.bounds"), RoomChatMessageBubbles.ALERT);
|
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.error.cmd_setspeed.bounds"), RoomChatMessageBubbles.ALERT);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enforce maximum speed of 10 regardless of config.
|
||||||
|
if (newSpeed > 10) {
|
||||||
|
newSpeed = 10;
|
||||||
|
gameClient.getHabbo().whisper("Speed cannot be set above 10. Setting speed to 10.", RoomChatMessageBubbles.ALERT);
|
||||||
|
}
|
||||||
|
|
||||||
room.setRollerSpeed(newSpeed);
|
room.setRollerSpeed(newSpeed);
|
||||||
|
|
||||||
gameClient.getHabbo().whisper(Emulator.getTexts().getValue("commands.succes.cmd_setspeed").replace("%oldspeed%", oldSpeed + "").replace("%newspeed%", newSpeed + ""), RoomChatMessageBubbles.ALERT);
|
gameClient.getHabbo().whisper(
|
||||||
|
Emulator.getTexts().getValue("commands.succes.cmd_setspeed")
|
||||||
|
.replace("%oldspeed%", oldSpeed + "")
|
||||||
|
.replace("%newspeed%", newSpeed + ""),
|
||||||
|
RoomChatMessageBubbles.ALERT
|
||||||
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1237,6 +1237,32 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
|
|||||||
final long millis = System.currentTimeMillis();
|
final long millis = System.currentTimeMillis();
|
||||||
|
|
||||||
for (Habbo habbo : this.currentHabbos.values()) {
|
for (Habbo habbo : this.currentHabbos.values()) {
|
||||||
|
RoomUnit unit = habbo.getRoomUnit();
|
||||||
|
// Only run loop detection if the unit is on a roller.
|
||||||
|
if (!unit.hasStatus(RoomUnitStatus.MOVE) && isOnRoller(unit)) {
|
||||||
|
double curX = unit.getX();
|
||||||
|
double curY = unit.getY();
|
||||||
|
double curZ = unit.getZ();
|
||||||
|
|
||||||
|
// Get or create a loop tracker for this unit.
|
||||||
|
LoopTracker tracker = loopTrackers.computeIfAbsent(unit, u -> new LoopTracker(curX, curY, curZ));
|
||||||
|
|
||||||
|
if (tracker.isSamePosition(curX, curY, curZ)) {
|
||||||
|
tracker.counter++;
|
||||||
|
// Compute threshold based on roller speed (max speed = 10).
|
||||||
|
int loopThreshold = Math.max(10, 3 + this.getRollerSpeed());
|
||||||
|
if (tracker.counter >= loopThreshold) {
|
||||||
|
LOGGER.warn("Loop detected for unit id " + unit.getId() +
|
||||||
|
" at position: x=" + curX + ", y=" + curY + ", z=" + curZ);
|
||||||
|
// Teleport unit back to the door tile.
|
||||||
|
RoomTile doorTile = this.getLayout().getDoorTile();
|
||||||
|
this.teleportRoomUnitToLocation(unit, doorTile.x, doorTile.y, doorTile.z);
|
||||||
|
tracker.counter = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tracker.update(curX, curY, curZ);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!foundRightHolder[0]) {
|
if (!foundRightHolder[0]) {
|
||||||
foundRightHolder[0] = habbo.getRoomUnit().getRightsLevel() != RoomRightLevels.NONE;
|
foundRightHolder[0] = habbo.getRoomUnit().getRightsLevel() != RoomRightLevels.NONE;
|
||||||
}
|
}
|
||||||
@ -1368,6 +1394,26 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<InteractionRoller> rollers = new ArrayList<>(this.roomSpecialTypes.getRollers().values());
|
||||||
|
|
||||||
|
// Sort rollers using a custom comparator that uses a projection of the roller's position
|
||||||
|
rollers.sort((r1, r2) -> {
|
||||||
|
// Convert the roller's rotation into an angle in radians.
|
||||||
|
double angle1 = Math.toRadians(r1.getRotation() * 45);
|
||||||
|
double angle2 = Math.toRadians(r2.getRotation() * 45);
|
||||||
|
|
||||||
|
// Compute the movement vector for each roller (a unit vector in its direction)
|
||||||
|
double vx1 = Math.cos(angle1);
|
||||||
|
double vy1 = Math.sin(angle1);
|
||||||
|
double vx2 = Math.cos(angle2);
|
||||||
|
double vy2 = Math.sin(angle2);
|
||||||
|
|
||||||
|
// Calculate the projection of the roller's position along its movement vector
|
||||||
|
double proj1 = r1.getX() * vx1 + r1.getY() * vy1;
|
||||||
|
double proj2 = r2.getX() * vx2 + r2.getY() * vy2;
|
||||||
|
|
||||||
|
return Double.compare(proj1, proj2);
|
||||||
|
});
|
||||||
if (this.rollerSpeed != -1 && this.rollerCycle >= this.rollerSpeed) {
|
if (this.rollerSpeed != -1 && this.rollerCycle >= this.rollerSpeed) {
|
||||||
this.rollerCycle = 0;
|
this.rollerCycle = 0;
|
||||||
|
|
||||||
@ -4980,4 +5026,42 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
|
|||||||
THashSet<RoomUnit> roomUnits = getRoomUnits();
|
THashSet<RoomUnit> roomUnits = getRoomUnits();
|
||||||
return roomUnits.stream().filter(unit -> unit.getCurrentLocation() == tile).collect(Collectors.toSet());
|
return roomUnits.stream().filter(unit -> unit.getCurrentLocation() == tile).collect(Collectors.toSet());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
private static class LoopTracker {
|
||||||
|
double x, y, z;
|
||||||
|
int counter;
|
||||||
|
|
||||||
|
public LoopTracker(double x, double y, double z) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.z = z;
|
||||||
|
this.counter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSamePosition(double newX, double newY, double newZ) {
|
||||||
|
// Use an epsilon for double comparison if necessary.
|
||||||
|
final double EPSILON = 0.001;
|
||||||
|
return Math.abs(newX - x) < EPSILON && Math.abs(newY - y) < EPSILON && Math.abs(newZ - z) < EPSILON;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(double newX, double newY, double newZ) {
|
||||||
|
this.x = newX;
|
||||||
|
this.y = newY;
|
||||||
|
this.z = newZ;
|
||||||
|
this.counter = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isOnRoller(RoomUnit unit) {
|
||||||
|
RoomTile currentTile = unit.getCurrentLocation();
|
||||||
|
// Iterate over all rollers in the room.
|
||||||
|
for (HabboItem roller : this.roomSpecialTypes.getRollers().values()) {
|
||||||
|
if (roller.getX() == currentTile.x && roller.getY() == currentTile.y) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Map<RoomUnit, LoopTracker> loopTrackers = new ConcurrentHashMap<>();
|
||||||
|
}
|
@ -136,6 +136,19 @@ public class WiredHighscoreManager {
|
|||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (scoreType == WiredHighscoreScoreType.LONGESTTIME) {
|
||||||
|
return highscores
|
||||||
|
.collect(Collectors.groupingBy(h -> h.getUsers().hashCode()))
|
||||||
|
.entrySet()
|
||||||
|
.stream()
|
||||||
|
.map(e -> e.getValue().stream()
|
||||||
|
.max(Comparator.comparingInt(WiredHighscoreRow::getValue))
|
||||||
|
.orElse(null))
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.sorted(Comparator.comparingInt(WiredHighscoreRow::getValue).reversed())
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,8 @@ package com.eu.habbo.habbohotel.wired.highscores;
|
|||||||
public enum WiredHighscoreScoreType {
|
public enum WiredHighscoreScoreType {
|
||||||
PERTEAM(0),
|
PERTEAM(0),
|
||||||
MOSTWIN(1),
|
MOSTWIN(1),
|
||||||
CLASSIC(2);
|
CLASSIC(2),
|
||||||
|
LONGESTTIME(3);
|
||||||
|
|
||||||
public final int type;
|
public final int type;
|
||||||
|
|
||||||
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user