🆙 Updated the LoopTracker for rollers
This commit is contained in:
parent
3332bc7f9c
commit
d1ff6687d6
@ -700,6 +700,7 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.sendComposer(new UpdateStackHeightComposer(this, updatedTiles).compose());
|
||||
this.updateTiles(updatedTiles);
|
||||
for (RoomTile tile : updatedTiles) {
|
||||
@ -1188,6 +1189,47 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
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<>();
|
||||
|
||||
private static class LoopTracker {
|
||||
double x, y, z;
|
||||
int counter;
|
||||
RoomTile nextTile;
|
||||
|
||||
public LoopTracker(double x, double y, double z, RoomTile nextTile) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.counter = 0;
|
||||
this.nextTile = nextTile;
|
||||
}
|
||||
|
||||
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, RoomTile nextTile) {
|
||||
this.x = newX;
|
||||
this.y = newY;
|
||||
this.z = newZ;
|
||||
this.counter = 0;
|
||||
this.nextTile = nextTile;
|
||||
}
|
||||
}
|
||||
|
||||
private void cycle() {
|
||||
this.cycleOdd = !this.cycleOdd;
|
||||
this.cycleTimestamp = System.currentTimeMillis();
|
||||
@ -1238,31 +1280,97 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
|
||||
|
||||
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));
|
||||
LoopTracker tracker = loopTrackers.computeIfAbsent(unit, u -> {
|
||||
RoomTile nextTile = null;
|
||||
for (InteractionRoller roller : this.roomSpecialTypes.getRollers().values()) {
|
||||
RoomTile rollerTile = this.getLayout().getTile((short) roller.getX(), (short) roller.getY());
|
||||
RoomTile potentialNextTile = this.getLayout().getTileInFront(rollerTile, roller.getRotation());
|
||||
if (potentialNextTile != null) {
|
||||
nextTile = potentialNextTile;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return new LoopTracker(curX, curY, curZ, nextTile);
|
||||
});
|
||||
|
||||
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);
|
||||
InteractionRoller currentRoller = null;
|
||||
RoomTile currentTile = this.getLayout().getTile((short) curX, (short) curY);
|
||||
for (InteractionRoller roller : this.roomSpecialTypes.getRollers().values()) {
|
||||
if (roller.getX() == currentTile.x && roller.getY() == currentTile.y) {
|
||||
currentRoller = roller;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RoomTile currentCalculatedNextTile = null;
|
||||
if (currentRoller != null) {
|
||||
RoomTile rollerTile = this.getLayout().getTile((short) currentRoller.getX(), (short) currentRoller.getY());
|
||||
currentCalculatedNextTile = this.getLayout().getTileInFront(rollerTile, currentRoller.getRotation());
|
||||
}
|
||||
|
||||
if (currentTile != null && unit.getGoal() != null) {
|
||||
double distanceToGoal = Math.hypot(unit.getGoal().x - currentTile.x, unit.getGoal().y - currentTile.y);
|
||||
final double ACCEPTABLE_DISTANCE = 0.5; // adjust as needed
|
||||
if (distanceToGoal <= ACCEPTABLE_DISTANCE) {
|
||||
tracker.update(curX, curY, curZ, currentCalculatedNextTile);
|
||||
tracker.counter = 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
boolean nextTileHasRoller = false;
|
||||
if (currentCalculatedNextTile != null) {
|
||||
for (InteractionRoller roller : this.roomSpecialTypes.getRollers().values()) {
|
||||
if (roller.getX() == currentCalculatedNextTile.x && roller.getY() == currentCalculatedNextTile.y) {
|
||||
nextTileHasRoller = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (currentCalculatedNextTile != null && !nextTileHasRoller) {
|
||||
tracker.update(curX, curY, curZ, currentCalculatedNextTile);
|
||||
tracker.counter = 0;
|
||||
} else {
|
||||
if (unit.getGoal() != null && tracker.nextTile != null &&
|
||||
unit.getGoal().x == tracker.nextTile.x && unit.getGoal().y == tracker.nextTile.y) {
|
||||
tracker.counter = 0;
|
||||
} else {
|
||||
tracker.counter++;
|
||||
int loopThreshold = Math.max(10, 3 + this.getRollerSpeed());
|
||||
if (tracker.counter >= loopThreshold) {
|
||||
RoomTile doorTile = this.getLayout().getDoorTile();
|
||||
unit.setBodyRotation(RoomUserRotation.values()[this.getLayout().getDoorDirection()]);
|
||||
unit.setHeadRotation(RoomUserRotation.values()[this.getLayout().getDoorDirection()]);
|
||||
this.teleportRoomUnitToLocation(unit, doorTile.x, doorTile.y, doorTile.z);
|
||||
tracker.counter = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tracker.update(curX, curY, curZ);
|
||||
InteractionRoller currentRoller = null;
|
||||
RoomTile currentTile = this.getLayout().getTile((short) curX, (short) curY);
|
||||
for (InteractionRoller roller : this.roomSpecialTypes.getRollers().values()) {
|
||||
if (roller.getX() == currentTile.x && roller.getY() == currentTile.y) {
|
||||
currentRoller = roller;
|
||||
break;
|
||||
}
|
||||
}
|
||||
RoomTile nextTile = null;
|
||||
if (currentRoller != null) {
|
||||
RoomTile rollerTile = this.getLayout().getTile((short) currentRoller.getX(), (short) currentRoller.getY());
|
||||
nextTile = this.getLayout().getTileInFront(rollerTile, currentRoller.getRotation());
|
||||
}
|
||||
tracker.update(curX, curY, curZ, nextTile);
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundRightHolder[0]) {
|
||||
foundRightHolder[0] = habbo.getRoomUnit().getRightsLevel() != RoomRightLevels.NONE;
|
||||
}
|
||||
@ -1314,7 +1422,6 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
|
||||
this.sendComposer(new RoomUserIgnoredComposer(habbo, RoomUserIgnoredComposer.UNIGNORED).compose());
|
||||
}
|
||||
|
||||
// Substract 1 from the chatCounter every odd cycle, which is every (500ms * 2).
|
||||
if (this.cycleOdd && habbo.getHabboStats().chatCounter.get() > 0) {
|
||||
habbo.getHabboStats().chatCounter.decrementAndGet();
|
||||
}
|
||||
@ -1396,19 +1503,15 @@ 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;
|
||||
|
||||
@ -1442,7 +1545,6 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
// itemsOnRoller.addAll(this.getItemsAt(rollerTile));
|
||||
itemsOnRoller.remove(roller);
|
||||
|
||||
if (!rollerTile.hasUnits() && itemsOnRoller.isEmpty())
|
||||
@ -1707,7 +1809,6 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean cycleRoomUnit(RoomUnit unit, RoomUnitType type) {
|
||||
boolean update = unit.needsStatusUpdate();
|
||||
if (unit.hasStatus(RoomUnitStatus.SIGN)) {
|
||||
@ -3049,6 +3150,7 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
|
||||
|
||||
return pets;
|
||||
}
|
||||
|
||||
public THashSet<Habbo> getHabbosAt(short x, short y) {
|
||||
return this.getHabbosAt(this.layout.getTile(x, y));
|
||||
}
|
||||
@ -3134,7 +3236,6 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
|
||||
roomUnit.setPreviousLocationZ(z);
|
||||
this.updateRoomUnit(roomUnit);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -4953,6 +5054,7 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
|
||||
}
|
||||
|
||||
public FurnitureMovementError slideFurniTo(HabboItem item, RoomTile tile, int rotation) {
|
||||
|
||||
RoomTile oldLocation = this.layout.getTile(item.getX(), item.getY());
|
||||
|
||||
HabboItem topItem = this.getTopItemAt(tile.x, tile.y);
|
||||
@ -4976,6 +5078,7 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
|
||||
item.setRotation(rotation);
|
||||
|
||||
//Place at new position
|
||||
|
||||
if (magicTile) {
|
||||
item.setZ(tile.z);
|
||||
item.setExtradata("" + item.getZ() * 100);
|
||||
@ -5026,42 +5129,4 @@ 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<>();
|
||||
}
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user