🆙 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>
|
||||
</option>
|
||||
</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>
|
@ -26,14 +26,27 @@ public class SetSpeedCommand extends Command {
|
||||
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);
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -1237,6 +1237,32 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
|
||||
final long millis = System.currentTimeMillis();
|
||||
|
||||
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]) {
|
||||
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) {
|
||||
this.rollerCycle = 0;
|
||||
|
||||
@ -4980,4 +5026,42 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
|
||||
THashSet<RoomUnit> roomUnits = getRoomUnits();
|
||||
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());
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,8 @@ package com.eu.habbo.habbohotel.wired.highscores;
|
||||
public enum WiredHighscoreScoreType {
|
||||
PERTEAM(0),
|
||||
MOSTWIN(1),
|
||||
CLASSIC(2);
|
||||
CLASSIC(2),
|
||||
LONGESTTIME(3);
|
||||
|
||||
public final int type;
|
||||
|
||||
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user