You've already forked Arcturus-Morningstar-Extended
mirror of
https://github.com/duckietm/Arcturus-Morningstar-Extended.git
synced 2026-06-19 15:06:19 +00:00
+61
-7
@@ -1,23 +1,24 @@
|
||||
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.messages.outgoing.rooms.items.ItemStateComposer;
|
||||
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 +44,65 @@ 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;
|
||||
|
||||
RoomTile goal = roomUnit.getGoal();
|
||||
if (goal != null && goal.x == this.getX() && goal.y == this.getY()) {
|
||||
this.kick(room, roomUnit, 55);
|
||||
} else {
|
||||
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);
|
||||
|
||||
if (this.lastDribbleDirection != null && walkDir.getRot() == this.lastDribbleDirection.getRot()) {
|
||||
this.kick(room, roomUnit, 55);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.currentThread != null) {
|
||||
this.currentThread.dead = true;
|
||||
this.currentThread = null;
|
||||
}
|
||||
this.setExtradata("0");
|
||||
room.sendComposer(new ItemStateComposer(this).compose());
|
||||
}
|
||||
|
||||
@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()))) {
|
||||
this.kick(room, unit, 55);
|
||||
}
|
||||
}
|
||||
|
||||
private void kick(Room room, RoomUnit kicker, int momentum) {
|
||||
boolean wasMoving = this.currentThread != null && !this.currentThread.dead && !this.currentThread.isDribble();
|
||||
|
||||
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());
|
||||
boolean zigzag = wasMoving && momentum > 0;
|
||||
|
||||
this.currentThread = new RebugKickBallAction(this, room, direction, momentum, zigzag);
|
||||
Emulator.getThreading().run(this.currentThread, 50);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,39 +4,56 @@ 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.Habbo;
|
||||
import com.eu.habbo.habbohotel.users.HabboItem;
|
||||
import com.eu.habbo.messages.outgoing.rooms.items.FloorItemOnRollerComposer;
|
||||
import com.eu.habbo.messages.outgoing.rooms.items.ItemStateComposer;
|
||||
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) {
|
||||
private final boolean zigzag;
|
||||
private Direction8 zigzagA;
|
||||
private Direction8 zigzagB;
|
||||
private boolean zigzagSide = false;
|
||||
|
||||
private int tilesSinceBounce = -1;
|
||||
|
||||
public RebugKickBallAction(HabboItem ball, Room room, Direction8 direction, int momentum) {
|
||||
this(ball, room, direction, momentum, false);
|
||||
}
|
||||
|
||||
public RebugKickBallAction(HabboItem ball, Room room, Direction8 direction, int momentum, boolean zigzag) {
|
||||
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);
|
||||
this.zigzag = zigzag && !this.isDribble;
|
||||
|
||||
if (this.zigzag) {
|
||||
this.zigzagA = direction.rotateDirection45Degrees(false);
|
||||
this.zigzagB = direction.rotateDirection45Degrees(true);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isDribble() {
|
||||
return this.isDribble;
|
||||
}
|
||||
|
||||
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;
|
||||
if (tile.getState() != RoomTileState.OPEN) return true;
|
||||
return x == this.room.getLayout().getDoorX() && y == this.room.getLayout().getDoorY();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -44,34 +61,110 @@ public class RebugKickBallAction implements Runnable {
|
||||
if (this.dead || !this.room.isLoaded()) return;
|
||||
|
||||
try {
|
||||
int nextX = this.ball.getX() + this.direction.getDiffX();
|
||||
int nextY = this.ball.getY() + this.direction.getDiffY();
|
||||
int nextX;
|
||||
int nextY;
|
||||
Direction8 moveDir;
|
||||
|
||||
if (isTileBlocked(nextX, nextY)) {
|
||||
this.direction = this.direction.rotateDirection180Degrees();
|
||||
if (this.zigzag) {
|
||||
Direction8 preferred = this.zigzagSide ? this.zigzagB : this.zigzagA;
|
||||
Direction8 fallback = this.zigzagSide ? this.zigzagA : this.zigzagB;
|
||||
|
||||
nextX = this.ball.getX() + preferred.getDiffX();
|
||||
nextY = this.ball.getY() + preferred.getDiffY();
|
||||
|
||||
if (isTileBlocked(nextX, nextY)) {
|
||||
nextX = this.ball.getX() + fallback.getDiffX();
|
||||
nextY = this.ball.getY() + fallback.getDiffY();
|
||||
|
||||
if (isTileBlocked(nextX, nextY)) {
|
||||
nextX = this.ball.getX() + this.direction.getDiffX();
|
||||
nextY = this.ball.getY() + this.direction.getDiffY();
|
||||
|
||||
if (isTileBlocked(nextX, nextY)) {
|
||||
this.stopBall();
|
||||
return;
|
||||
}
|
||||
moveDir = this.direction;
|
||||
} else {
|
||||
moveDir = fallback;
|
||||
}
|
||||
} else {
|
||||
moveDir = preferred;
|
||||
this.zigzagSide = !this.zigzagSide;
|
||||
}
|
||||
} else {
|
||||
nextX = this.ball.getX() + this.direction.getDiffX();
|
||||
nextY = this.ball.getY() + this.direction.getDiffY();
|
||||
|
||||
if (isTileBlocked(nextX, nextY)) {
|
||||
int dx = this.direction.getDiffX();
|
||||
int dy = this.direction.getDiffY();
|
||||
|
||||
if (dx != 0 && dy != 0) {
|
||||
boolean xBlocked = isTileBlocked(this.ball.getX() + dx, this.ball.getY());
|
||||
boolean yBlocked = isTileBlocked(this.ball.getX(), this.ball.getY() + dy);
|
||||
|
||||
if (xBlocked && !yBlocked) {
|
||||
this.direction = Direction8.fromDelta(-dx, dy);
|
||||
} else if (!xBlocked && yBlocked) {
|
||||
this.direction = Direction8.fromDelta(dx, -dy);
|
||||
} else {
|
||||
this.direction = this.direction.rotateDirection180Degrees();
|
||||
}
|
||||
} else {
|
||||
this.direction = this.direction.rotateDirection180Degrees();
|
||||
}
|
||||
|
||||
this.tilesSinceBounce = 0;
|
||||
nextX = this.ball.getX() + this.direction.getDiffX();
|
||||
nextY = this.ball.getY() + this.direction.getDiffY();
|
||||
}
|
||||
moveDir = this.direction;
|
||||
}
|
||||
|
||||
RoomTile nextTile = this.room.getLayout().getTile((short) nextX, (short) nextY);
|
||||
if (nextTile == null) return;
|
||||
if (nextTile == null) {
|
||||
this.stopBall();
|
||||
return;
|
||||
}
|
||||
|
||||
RoomTile oldTile = this.room.getLayout().getTile(this.ball.getX(), this.ball.getY());
|
||||
double oldZ = this.ball.getZ();
|
||||
|
||||
this.ball.setRotation(this.direction.getRot());
|
||||
this.ball.setRotation(moveDir.getRot());
|
||||
this.ball.setX(nextTile.x);
|
||||
this.ball.setY(nextTile.y);
|
||||
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);
|
||||
if (!this.zigzag && this.tilesSinceBounce >= 0) {
|
||||
this.tilesSinceBounce++;
|
||||
}
|
||||
|
||||
if (!this.zigzag && this.tilesSinceBounce > 1 && !this.isDribble) {
|
||||
THashSet<Habbo> habbos = this.room.getHabbosAt(nextTile.x, nextTile.y);
|
||||
if (!habbos.isEmpty()) {
|
||||
this.direction = this.direction.rotateDirection180Degrees();
|
||||
this.tilesSinceBounce = 0;
|
||||
}
|
||||
}
|
||||
|
||||
this.ball.setExtradata(this.isDribble ? "2" : "5");
|
||||
this.room.sendComposer(new ItemStateComposer(this.ball).compose());
|
||||
|
||||
this.momentum -= 11;
|
||||
|
||||
if (!this.isDribble) {
|
||||
long delay = getDelayForMomentum(this.momentum);
|
||||
if (delay > 0) {
|
||||
Emulator.getThreading().run(this, delay);
|
||||
} else {
|
||||
this.stopBall();
|
||||
}
|
||||
} else {
|
||||
this.dead = true;
|
||||
}
|
||||
|
||||
// Update tiles
|
||||
this.room.updateTile(oldTile);
|
||||
this.room.updateTile(nextTile);
|
||||
|
||||
@@ -81,18 +174,20 @@ public class RebugKickBallAction implements Runnable {
|
||||
}
|
||||
this.room.getItemsAt(nextTile).add(this.ball);
|
||||
|
||||
// Send rolling animation
|
||||
this.room.sendComposer(new FloorItemOnRollerComposer(
|
||||
this.ball, null, oldTile, oldZ, nextTile, this.ball.getZ(), 0.0D, this.room
|
||||
).compose());
|
||||
|
||||
// Decay momentum
|
||||
this.momentum -= 11;
|
||||
} catch (Exception e) {
|
||||
this.dead = true;
|
||||
this.stopBall();
|
||||
}
|
||||
}
|
||||
|
||||
private void stopBall() {
|
||||
this.dead = true;
|
||||
this.ball.setExtradata("0");
|
||||
this.room.sendComposer(new ItemStateComposer(this.ball).compose());
|
||||
}
|
||||
|
||||
private long getDelayForMomentum(int momentum) {
|
||||
switch (momentum) {
|
||||
case 55: return 100L;
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user