diff --git a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/InteractionRebugFootball.java b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/InteractionRebugFootball.java index 98666d50..969ba5b2 100644 --- a/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/InteractionRebugFootball.java +++ b/Emulator/src/main/java/com/eu/habbo/habbohotel/items/interactions/games/football/InteractionRebugFootball.java @@ -1,23 +1,23 @@ package com.eu.habbo.habbohotel.items.interactions.games.football; import com.eu.habbo.Emulator; +import com.eu.habbo.habbohotel.gameclients.GameClient; import com.eu.habbo.habbohotel.items.Item; import com.eu.habbo.habbohotel.items.interactions.InteractionDefault; import com.eu.habbo.habbohotel.rooms.Room; +import com.eu.habbo.habbohotel.rooms.RoomLayout; +import com.eu.habbo.habbohotel.rooms.RoomTile; import com.eu.habbo.habbohotel.rooms.RoomUnit; import com.eu.habbo.threading.runnables.RebugKickBallAction; +import com.eu.habbo.util.pathfinding.Direction8; import java.sql.ResultSet; import java.sql.SQLException; -/** - * Rebug-style football interaction. - * Uses simplified momentum-decay physics with 180-degree bounce. - * Set interaction_type to "rebug_football" on a ball item to use this instead of the default football physics. - */ public class InteractionRebugFootball extends InteractionDefault { private RebugKickBallAction currentThread; + private Direction8 lastDribbleDirection; public InteractionRebugFootball(ResultSet set, Item baseItem) throws SQLException { super(set, baseItem); @@ -43,12 +43,64 @@ public class InteractionRebugFootball extends InteractionDefault { public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { super.onWalkOn(roomUnit, room, objects); + Direction8 userDir = Direction8.getDirection(roomUnit.getBodyRotation().getValue()); + this.lastDribbleDirection = userDir; + + // If this tile is the user's final destination, they'll stop here → long shot + RoomTile goal = roomUnit.getGoal(); + if (goal != null && goal.x == this.getX() && goal.y == this.getY()) { + this.kick(room, roomUnit, 55); + } else { + // Dribble: ball moves 1 tile ahead of the user + this.kick(room, roomUnit, 0); + } + } + + @Override + public void onWalkOff(RoomUnit roomUnit, Room room, Object[] objects) throws Exception { + super.onWalkOff(roomUnit, room, objects); + + if (objects != null && objects.length >= 2 && objects[1] instanceof RoomTile && objects[0] instanceof RoomTile) { + RoomTile fromTile = (RoomTile) objects[0]; + RoomTile nextTile = (RoomTile) objects[1]; + + int dx = nextTile.x - fromTile.x; + int dy = nextTile.y - fromTile.y; + Direction8 walkDir = Direction8.fromDelta(dx, dy); + + // User is walking in the same direction as the ball was dribbled → long shot + if (this.lastDribbleDirection != null && walkDir.getRot() == this.lastDribbleDirection.getRot()) { + this.kick(room, roomUnit, 55); + return; + } + } + + // Walking sideways or away → just stop the ball + if (this.currentThread != null) { + this.currentThread.dead = true; + this.currentThread = null; + } + } + + @Override + public void onClick(GameClient client, Room room, Object[] objects) throws Exception { + super.onClick(client, room, objects); + + if (client == null) return; + RoomUnit unit = client.getHabbo().getRoomUnit(); + if (RoomLayout.tilesAdjecent(unit.getCurrentLocation(), room.getLayout().getTile(this.getX(), this.getY()))) { + // Long shot when clicking the ball + this.kick(room, unit, 55); + } + } + + private void kick(Room room, RoomUnit kicker, int momentum) { if (this.currentThread != null) { this.currentThread.dead = true; } - boolean hasPath = !roomUnit.getPath().isEmpty(); - this.currentThread = new RebugKickBallAction(this, room, roomUnit, hasPath); + Direction8 direction = Direction8.getDirection(kicker.getBodyRotation().getValue()); + this.currentThread = new RebugKickBallAction(this, room, direction, momentum); Emulator.getThreading().run(this.currentThread, 50); } } diff --git a/Emulator/src/main/java/com/eu/habbo/threading/runnables/RebugKickBallAction.java b/Emulator/src/main/java/com/eu/habbo/threading/runnables/RebugKickBallAction.java index 55694364..86af53eb 100644 --- a/Emulator/src/main/java/com/eu/habbo/threading/runnables/RebugKickBallAction.java +++ b/Emulator/src/main/java/com/eu/habbo/threading/runnables/RebugKickBallAction.java @@ -4,38 +4,31 @@ import com.eu.habbo.Emulator; import com.eu.habbo.habbohotel.rooms.Room; import com.eu.habbo.habbohotel.rooms.RoomTile; import com.eu.habbo.habbohotel.rooms.RoomTileState; -import com.eu.habbo.habbohotel.rooms.RoomUnit; import com.eu.habbo.habbohotel.users.HabboItem; import com.eu.habbo.messages.outgoing.rooms.items.FloorItemOnRollerComposer; import com.eu.habbo.util.pathfinding.Direction8; import gnu.trove.set.hash.THashSet; -/** - * Alternative football physics based on the Rebug plugin. - * Uses momentum decay (ball slows down over time) and simple 180-degree bounce. - */ public class RebugKickBallAction implements Runnable { private final HabboItem ball; private final Room room; private Direction8 direction; private int momentum; + private boolean isDribble; public boolean dead = false; - public RebugKickBallAction(HabboItem ball, Room room, RoomUnit kicker, boolean hasPath) { + public RebugKickBallAction(HabboItem ball, Room room, Direction8 direction, int momentum) { this.ball = ball; this.room = room; - this.direction = Direction8.fromDelta( - ball.getX() - kicker.getX(), - ball.getY() - kicker.getY() - ); - this.momentum = hasPath ? 55 : 0; + this.direction = direction; + this.momentum = momentum; + this.isDribble = (momentum == 0); } private boolean isTileBlocked(int x, int y) { RoomTile tile = this.room.getLayout().getTile((short) x, (short) y); if (tile == null) return true; - if (tile.hasUnits()) return true; return tile.getState() != RoomTileState.OPEN; } @@ -65,10 +58,16 @@ public class RebugKickBallAction implements Runnable { this.ball.setZ(nextTile.getStackHeight()); this.ball.needsUpdate(true); - // Schedule next movement based on momentum - long delay = getDelayForMomentum(this.momentum); - if (delay > 0) { - Emulator.getThreading().run(this, delay); + // Schedule next movement + if (!this.isDribble) { + long delay = getDelayForMomentum(this.momentum); + if (delay > 0) { + Emulator.getThreading().run(this, delay); + } else { + this.dead = true; + } + } else { + this.dead = true; } // Update tiles