🆕 Added BuildTools to the Emulator
This commit is contained in:
parent
9d391865af
commit
2d207bc08a
@ -700,7 +700,6 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.sendComposer(new UpdateStackHeightComposer(this, updatedTiles).compose());
|
this.sendComposer(new UpdateStackHeightComposer(this, updatedTiles).compose());
|
||||||
this.updateTiles(updatedTiles);
|
this.updateTiles(updatedTiles);
|
||||||
for (RoomTile tile : updatedTiles) {
|
for (RoomTile tile : updatedTiles) {
|
||||||
@ -1235,7 +1234,6 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
|
|||||||
this.cycleTimestamp = System.currentTimeMillis();
|
this.cycleTimestamp = System.currentTimeMillis();
|
||||||
final boolean[] foundRightHolder = {false};
|
final boolean[] foundRightHolder = {false};
|
||||||
|
|
||||||
|
|
||||||
boolean loaded;
|
boolean loaded;
|
||||||
synchronized (this.loadLock) {
|
synchronized (this.loadLock) {
|
||||||
loaded = this.loaded;
|
loaded = this.loaded;
|
||||||
@ -1280,11 +1278,14 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
|
|||||||
|
|
||||||
for (Habbo habbo : this.currentHabbos.values()) {
|
for (Habbo habbo : this.currentHabbos.values()) {
|
||||||
RoomUnit unit = habbo.getRoomUnit();
|
RoomUnit unit = habbo.getRoomUnit();
|
||||||
|
// Only run loop detection if the unit is on a roller.
|
||||||
if (!unit.hasStatus(RoomUnitStatus.MOVE) && isOnRoller(unit)) {
|
if (!unit.hasStatus(RoomUnitStatus.MOVE) && isOnRoller(unit)) {
|
||||||
|
// Get the current coordinates of the unit on the roller:
|
||||||
double curX = unit.getX();
|
double curX = unit.getX();
|
||||||
double curY = unit.getY();
|
double curY = unit.getY();
|
||||||
double curZ = unit.getZ();
|
double curZ = unit.getZ();
|
||||||
|
|
||||||
|
// Get or create a loop tracker for this unit.
|
||||||
LoopTracker tracker = loopTrackers.computeIfAbsent(unit, u -> {
|
LoopTracker tracker = loopTrackers.computeIfAbsent(unit, u -> {
|
||||||
RoomTile nextTile = null;
|
RoomTile nextTile = null;
|
||||||
for (InteractionRoller roller : this.roomSpecialTypes.getRollers().values()) {
|
for (InteractionRoller roller : this.roomSpecialTypes.getRollers().values()) {
|
||||||
@ -1292,13 +1293,15 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
|
|||||||
RoomTile potentialNextTile = this.getLayout().getTileInFront(rollerTile, roller.getRotation());
|
RoomTile potentialNextTile = this.getLayout().getTileInFront(rollerTile, roller.getRotation());
|
||||||
if (potentialNextTile != null) {
|
if (potentialNextTile != null) {
|
||||||
nextTile = potentialNextTile;
|
nextTile = potentialNextTile;
|
||||||
break;
|
break; // use the first valid next tile found
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new LoopTracker(curX, curY, curZ, nextTile);
|
return new LoopTracker(curX, curY, curZ, nextTile);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Check if the unit’s current position is the same as last cycle.
|
||||||
if (tracker.isSamePosition(curX, curY, curZ)) {
|
if (tracker.isSamePosition(curX, curY, curZ)) {
|
||||||
|
// Find the roller that is on the current tile.
|
||||||
InteractionRoller currentRoller = null;
|
InteractionRoller currentRoller = null;
|
||||||
RoomTile currentTile = this.getLayout().getTile((short) curX, (short) curY);
|
RoomTile currentTile = this.getLayout().getTile((short) curX, (short) curY);
|
||||||
for (InteractionRoller roller : this.roomSpecialTypes.getRollers().values()) {
|
for (InteractionRoller roller : this.roomSpecialTypes.getRollers().values()) {
|
||||||
@ -1308,12 +1311,16 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Calculate the next tile using the current roller.
|
||||||
RoomTile currentCalculatedNextTile = null;
|
RoomTile currentCalculatedNextTile = null;
|
||||||
if (currentRoller != null) {
|
if (currentRoller != null) {
|
||||||
RoomTile rollerTile = this.getLayout().getTile((short) currentRoller.getX(), (short) currentRoller.getY());
|
RoomTile rollerTile = this.getLayout().getTile((short) currentRoller.getX(), (short) currentRoller.getY());
|
||||||
currentCalculatedNextTile = this.getLayout().getTileInFront(rollerTile, currentRoller.getRotation());
|
currentCalculatedNextTile = this.getLayout().getTileInFront(rollerTile, currentRoller.getRotation());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Here we add a check:
|
||||||
|
// If the unit's goal is either on the roller itself or is within a small distance (epsilon) of the roller tile,
|
||||||
|
// then we assume the habbo is "almost there" and do not increment the loop counter.
|
||||||
if (currentTile != null && unit.getGoal() != null) {
|
if (currentTile != null && unit.getGoal() != null) {
|
||||||
double distanceToGoal = Math.hypot(unit.getGoal().x - currentTile.x, unit.getGoal().y - currentTile.y);
|
double distanceToGoal = Math.hypot(unit.getGoal().x - currentTile.x, unit.getGoal().y - currentTile.y);
|
||||||
final double ACCEPTABLE_DISTANCE = 0.5; // adjust as needed
|
final double ACCEPTABLE_DISTANCE = 0.5; // adjust as needed
|
||||||
@ -1324,6 +1331,8 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Otherwise, use your normal loop detection logic:
|
||||||
|
// (for example, checking if the next tile contains a roller, etc.)
|
||||||
boolean nextTileHasRoller = false;
|
boolean nextTileHasRoller = false;
|
||||||
if (currentCalculatedNextTile != null) {
|
if (currentCalculatedNextTile != null) {
|
||||||
for (InteractionRoller roller : this.roomSpecialTypes.getRollers().values()) {
|
for (InteractionRoller roller : this.roomSpecialTypes.getRollers().values()) {
|
||||||
@ -1354,6 +1363,7 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// Unit has moved; update tracker accordingly.
|
||||||
InteractionRoller currentRoller = null;
|
InteractionRoller currentRoller = null;
|
||||||
RoomTile currentTile = this.getLayout().getTile((short) curX, (short) curY);
|
RoomTile currentTile = this.getLayout().getTile((short) curX, (short) curY);
|
||||||
for (InteractionRoller roller : this.roomSpecialTypes.getRollers().values()) {
|
for (InteractionRoller roller : this.roomSpecialTypes.getRollers().values()) {
|
||||||
@ -1371,7 +1381,7 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!foundRightHolder[0]) {
|
if (!foundRightHolder[0]) {
|
||||||
foundRightHolder[0] = habbo.getRoomUnit().getRightsLevel() != RoomRightLevels.NONE;
|
foundRightHolder[0] = habbo.getRoomUnit().getRightsLevel() != RoomRightLevels.NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1422,6 +1432,7 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
|
|||||||
this.sendComposer(new RoomUserIgnoredComposer(habbo, RoomUserIgnoredComposer.UNIGNORED).compose());
|
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) {
|
if (this.cycleOdd && habbo.getHabboStats().chatCounter.get() > 0) {
|
||||||
habbo.getHabboStats().chatCounter.decrementAndGet();
|
habbo.getHabboStats().chatCounter.decrementAndGet();
|
||||||
}
|
}
|
||||||
@ -1503,15 +1514,19 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
|
|||||||
|
|
||||||
List<InteractionRoller> rollers = new ArrayList<>(this.roomSpecialTypes.getRollers().values());
|
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) -> {
|
rollers.sort((r1, r2) -> {
|
||||||
|
// Convert the roller's rotation into an angle in radians.
|
||||||
double angle1 = Math.toRadians(r1.getRotation() * 45);
|
double angle1 = Math.toRadians(r1.getRotation() * 45);
|
||||||
double angle2 = Math.toRadians(r2.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 vx1 = Math.cos(angle1);
|
||||||
double vy1 = Math.sin(angle1);
|
double vy1 = Math.sin(angle1);
|
||||||
double vx2 = Math.cos(angle2);
|
double vx2 = Math.cos(angle2);
|
||||||
double vy2 = Math.sin(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 proj1 = r1.getX() * vx1 + r1.getY() * vy1;
|
||||||
double proj2 = r2.getX() * vx2 + r2.getY() * vy2;
|
double proj2 = r2.getX() * vx2 + r2.getY() * vy2;
|
||||||
|
|
||||||
@ -1545,13 +1560,18 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// itemsOnRoller.addAll(this.getItemsAt(rollerTile));
|
||||||
itemsOnRoller.remove(roller);
|
itemsOnRoller.remove(roller);
|
||||||
|
|
||||||
if (!rollerTile.hasUnits() && itemsOnRoller.isEmpty())
|
if (!rollerTile.hasUnits() && itemsOnRoller.isEmpty())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
// RoomTile currentTile = Room.this.layout.getTile(roller.getX(), roller.getY());
|
||||||
RoomTile tileInFront = Room.this.layout.getTileInFront(Room.this.layout.getTile(roller.getX(), roller.getY()), roller.getRotation());
|
RoomTile tileInFront = Room.this.layout.getTileInFront(Room.this.layout.getTile(roller.getX(), roller.getY()), roller.getRotation());
|
||||||
|
|
||||||
|
// LOGGER.debug("Roller at: (" + roller.getX() + ", " + roller.getY() + "), Rotation: " + roller.getRotation());
|
||||||
|
// LOGGER.debug("Next tile calculated: (" + (tileInFront != null ? tileInFront.x : "NULL") + ", " + (tileInFront != null ? tileInFront.y : "NULL") + ")");
|
||||||
|
|
||||||
if (tileInFront == null)
|
if (tileInFront == null)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -1809,6 +1829,7 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private boolean cycleRoomUnit(RoomUnit unit, RoomUnitType type) {
|
private boolean cycleRoomUnit(RoomUnit unit, RoomUnitType type) {
|
||||||
boolean update = unit.needsStatusUpdate();
|
boolean update = unit.needsStatusUpdate();
|
||||||
if (unit.hasStatus(RoomUnitStatus.SIGN)) {
|
if (unit.hasStatus(RoomUnitStatus.SIGN)) {
|
||||||
@ -3236,6 +3257,7 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
|
|||||||
roomUnit.setPreviousLocationZ(z);
|
roomUnit.setPreviousLocationZ(z);
|
||||||
this.updateRoomUnit(roomUnit);
|
this.updateRoomUnit(roomUnit);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5053,32 +5075,44 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
|
|||||||
return FurnitureMovementError.NONE;
|
return FurnitureMovementError.NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FurnitureMovementError slideFurniTo(HabboItem item, RoomTile tile, int rotation) {
|
public FurnitureMovementError moveFurniTo(HabboItem item, RoomTile tile, int rotation, double z, Habbo actor, boolean sendUpdates, boolean checkForUnits) {
|
||||||
|
if (tile == null) {
|
||||||
|
return FurnitureMovementError.INVALID_MOVE;
|
||||||
|
}
|
||||||
RoomTile oldLocation = this.layout.getTile(item.getX(), item.getY());
|
RoomTile oldLocation = this.layout.getTile(item.getX(), item.getY());
|
||||||
|
boolean pluginHelper = false;
|
||||||
|
|
||||||
HabboItem topItem = this.getTopItemAt(tile.x, tile.y);
|
|
||||||
|
|
||||||
boolean magicTile = item instanceof InteractionStackHelper || item instanceof InteractionTileWalkMagic;
|
if (Emulator.getPluginManager().isRegistered(FurnitureMovedEvent.class, true)) {
|
||||||
|
FurnitureMovedEvent event = Emulator.getPluginManager().fireEvent(new FurnitureMovedEvent(item, actor, oldLocation, tile));
|
||||||
Optional<HabboItem> stackHelper = this.getItemsAt(tile).stream().filter(i -> i instanceof InteractionStackHelper).findAny();THashSet<RoomTile> occupiedTiles = this.layout.getTilesAt(tile, item.getBaseItem().getWidth(), item.getBaseItem().getLength(), rotation);
|
if(event.isCancelled()) {
|
||||||
|
return FurnitureMovementError.CANCEL_PLUGIN_MOVE;
|
||||||
List<Pair<RoomTile, THashSet<HabboItem>>> tileFurniList = new ArrayList<>();
|
}
|
||||||
for (RoomTile t : occupiedTiles) {
|
pluginHelper = event.hasPluginHelper();
|
||||||
tileFurniList.add(Pair.create(t, this.getItemsAt(t)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!magicTile && !item.canStackAt(this, tileFurniList)) {
|
boolean magicTile = item instanceof InteractionStackHelper;
|
||||||
return FurnitureMovementError.CANT_STACK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
THashSet<RoomTile> occupiedTiles = this.layout.getTilesAt(tile, item.getBaseItem().getWidth(), item.getBaseItem().getLength(), rotation);
|
||||||
THashSet<RoomTile> oldOccupiedTiles = this.layout.getTilesAt(this.layout.getTile(item.getX(), item.getY()), item.getBaseItem().getWidth(), item.getBaseItem().getLength(), item.getRotation());
|
THashSet<RoomTile> oldOccupiedTiles = this.layout.getTilesAt(this.layout.getTile(item.getX(), item.getY()), item.getBaseItem().getWidth(), item.getBaseItem().getLength(), item.getRotation());
|
||||||
|
|
||||||
int oldRotation = item.getRotation();
|
if (item.getRotation() != rotation) {
|
||||||
item.setRotation(rotation);
|
item.setRotation(rotation);
|
||||||
|
}
|
||||||
|
|
||||||
//Place at new position
|
if(z > MAXIMUM_FURNI_HEIGHT) return FurnitureMovementError.CANT_STACK;
|
||||||
|
if(z < this.getLayout().getHeightAtSquare(tile.x, tile.y)) return FurnitureMovementError.CANT_STACK; //prevent furni going under the floor
|
||||||
|
|
||||||
|
if (Emulator.getPluginManager().isRegistered(FurnitureBuildheightEvent.class, true)) {
|
||||||
|
FurnitureBuildheightEvent event = Emulator.getPluginManager().fireEvent(new FurnitureBuildheightEvent(item, actor, 0.00, z));
|
||||||
|
if (event.hasChangedHeight()) {
|
||||||
|
z = event.getUpdatedHeight();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
item.setX(tile.x);
|
||||||
|
item.setY(tile.y);
|
||||||
|
item.setZ(z);
|
||||||
if (magicTile) {
|
if (magicTile) {
|
||||||
item.setZ(tile.z);
|
item.setZ(tile.z);
|
||||||
item.setExtradata("" + item.getZ() * 100);
|
item.setExtradata("" + item.getZ() * 100);
|
||||||
@ -5086,12 +5120,31 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
|
|||||||
if (item.getZ() > MAXIMUM_FURNI_HEIGHT) {
|
if (item.getZ() > MAXIMUM_FURNI_HEIGHT) {
|
||||||
item.setZ(MAXIMUM_FURNI_HEIGHT);
|
item.setZ(MAXIMUM_FURNI_HEIGHT);
|
||||||
}
|
}
|
||||||
double offset = this.getStackHeight(tile.x, tile.y, false, item) - item.getZ();
|
|
||||||
this.sendComposer(new FloorItemOnRollerComposer(item, null, tile, offset, this).compose());
|
//Update Furniture
|
||||||
|
item.onMove(this, oldLocation, tile);
|
||||||
|
item.needsUpdate(true);
|
||||||
|
Emulator.getThreading().run(item);
|
||||||
|
|
||||||
|
if(sendUpdates) {
|
||||||
|
this.sendComposer(new FloorItemUpdateComposer(item).compose());
|
||||||
|
}
|
||||||
|
|
||||||
|
//Update old & new tiles
|
||||||
|
occupiedTiles.removeAll(oldOccupiedTiles);
|
||||||
|
occupiedTiles.addAll(oldOccupiedTiles);
|
||||||
|
this.updateTiles(occupiedTiles);
|
||||||
|
|
||||||
//Update Habbos at old position
|
//Update Habbos at old position
|
||||||
for (RoomTile t : occupiedTiles) {
|
for (RoomTile t : occupiedTiles) {
|
||||||
this.updateHabbosAt(t.x, t.y);
|
this.updateHabbosAt(
|
||||||
|
t.x,
|
||||||
|
t.y,
|
||||||
|
this.getHabbosAt(t.x, t.y)
|
||||||
|
/*.stream()
|
||||||
|
.filter(h -> !h.getRoomUnit().hasStatus(RoomUnitStatus.MOVE) || h.getRoomUnit().getGoal() == t)
|
||||||
|
.collect(Collectors.toCollection(THashSet::new))*/
|
||||||
|
);
|
||||||
this.updateBotsAt(t.x, t.y);
|
this.updateBotsAt(t.x, t.y);
|
||||||
}
|
}
|
||||||
return FurnitureMovementError.NONE;
|
return FurnitureMovementError.NONE;
|
||||||
|
@ -467,6 +467,7 @@ public class PacketManager {
|
|||||||
this.registerHandler(Incoming.LoveLockStartConfirmEvent, LoveLockStartConfirmEvent.class);
|
this.registerHandler(Incoming.LoveLockStartConfirmEvent, LoveLockStartConfirmEvent.class);
|
||||||
this.registerHandler(Incoming.RoomUnFavoriteEvent, RoomUnFavoriteEvent.class);
|
this.registerHandler(Incoming.RoomUnFavoriteEvent, RoomUnFavoriteEvent.class);
|
||||||
this.registerHandler(Incoming.UseRandomStateItemEvent, UseRandomStateItemEvent.class);
|
this.registerHandler(Incoming.UseRandomStateItemEvent, UseRandomStateItemEvent.class);
|
||||||
|
this.registerHandler(Incoming.UpdateFurniturePositionEvent, UpdateFurniturePositionEvent.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
void registerPolls() throws Exception {
|
void registerPolls() throws Exception {
|
||||||
|
@ -404,4 +404,7 @@ public class Incoming {
|
|||||||
public static final int UNKNOWN_SNOWSTORM_6024 = 6024;
|
public static final int UNKNOWN_SNOWSTORM_6024 = 6024;
|
||||||
public static final int UNKNOWN_SNOWSTORM_6025 = 6025;
|
public static final int UNKNOWN_SNOWSTORM_6025 = 6025;
|
||||||
public static final int SnowStormUserPickSnowballEvent = 6026;
|
public static final int SnowStormUserPickSnowballEvent = 6026;
|
||||||
|
|
||||||
|
// CUSTOM
|
||||||
|
public static final int UpdateFurniturePositionEvent = 10019;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
package com.eu.habbo.messages.incoming.rooms.items;
|
||||||
|
|
||||||
|
import com.eu.habbo.habbohotel.rooms.Room;
|
||||||
|
import com.eu.habbo.habbohotel.rooms.RoomTile;
|
||||||
|
import com.eu.habbo.habbohotel.users.HabboItem;
|
||||||
|
import com.eu.habbo.messages.incoming.MessageHandler;
|
||||||
|
import com.eu.habbo.messages.outgoing.rooms.items.FloorItemUpdateComposer;
|
||||||
|
|
||||||
|
public class UpdateFurniturePositionEvent extends MessageHandler {
|
||||||
|
@Override
|
||||||
|
public void handle() throws Exception {
|
||||||
|
Room room = this.client.getHabbo().getHabboInfo().getCurrentRoom();
|
||||||
|
|
||||||
|
if (room == null) return;
|
||||||
|
|
||||||
|
int furniId = this.packet.readInt();
|
||||||
|
HabboItem item = room.getHabboItem(furniId);
|
||||||
|
if (item == null) return;
|
||||||
|
|
||||||
|
int x = this.packet.readInt();
|
||||||
|
int y = this.packet.readInt();
|
||||||
|
double z = (double) this.packet.readInt() / 10000;
|
||||||
|
int rotation = this.packet.readInt();
|
||||||
|
RoomTile tile = room.getLayout().getTile((short) x, (short) y);
|
||||||
|
|
||||||
|
room.moveFurniTo(item, tile, rotation, z, this.client.getHabbo(), true, true);
|
||||||
|
this.client.sendResponse(new FloorItemUpdateComposer(item));
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user