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
🆙 Added Rebug football
-- Rebug Football Physics -- To use rebug football physics on a ball, set its interaction_type to 'rebug_football'. -- The default 'football' interaction uses the standard physics. -- -- Example: Change all footballs to use rebug physics: -- UPDATE items_base SET interaction_type = 'rebug_football' WHERE interaction_type = 'football'; -- -- Example: Change a specific ball item to use rebug physics: -- UPDATE items_base SET interaction_type = 'rebug_football' WHERE id = <item_base_id>; -- -- To revert back to default physics: -- UPDATE items_base SET interaction_type = 'football' WHERE interaction_type = 'rebug_football';
This commit is contained in:
@@ -17,6 +17,7 @@ import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.scoreboards
|
||||
import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.scoreboards.InteractionBattleBanzaiScoreboardYellow;
|
||||
import com.eu.habbo.habbohotel.items.interactions.games.football.InteractionFootball;
|
||||
import com.eu.habbo.habbohotel.items.interactions.games.football.InteractionFootballGate;
|
||||
import com.eu.habbo.habbohotel.items.interactions.games.football.InteractionRebugFootball;
|
||||
import com.eu.habbo.habbohotel.items.interactions.games.football.goals.InteractionFootballGoalBlue;
|
||||
import com.eu.habbo.habbohotel.items.interactions.games.football.goals.InteractionFootballGoalGreen;
|
||||
import com.eu.habbo.habbohotel.items.interactions.games.football.goals.InteractionFootballGoalRed;
|
||||
@@ -344,6 +345,7 @@ public class ItemManager {
|
||||
|
||||
|
||||
this.interactionsList.add(new ItemInteraction("football", InteractionFootball.class));
|
||||
this.interactionsList.add(new ItemInteraction("rebug_football", InteractionRebugFootball.class));
|
||||
this.interactionsList.add(new ItemInteraction("football_gate", InteractionFootballGate.class));
|
||||
this.interactionsList.add(new ItemInteraction("football_counter_blue", InteractionFootballScoreboardBlue.class));
|
||||
this.interactionsList.add(new ItemInteraction("football_counter_green", InteractionFootballScoreboardGreen.class));
|
||||
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
package com.eu.habbo.habbohotel.items.interactions.games.football;
|
||||
|
||||
import com.eu.habbo.Emulator;
|
||||
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.RoomUnit;
|
||||
import com.eu.habbo.threading.runnables.RebugKickBallAction;
|
||||
|
||||
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;
|
||||
|
||||
public InteractionRebugFootball(ResultSet set, Item baseItem) throws SQLException {
|
||||
super(set, baseItem);
|
||||
this.setExtradata("0");
|
||||
}
|
||||
|
||||
public InteractionRebugFootball(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) {
|
||||
super(id, userId, item, extradata, limitedStack, limitedSells);
|
||||
this.setExtradata("0");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canWalkOn(RoomUnit roomUnit, Room room, Object[] objects) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWalkable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWalkOn(RoomUnit roomUnit, Room room, Object[] objects) throws Exception {
|
||||
super.onWalkOn(roomUnit, room, objects);
|
||||
|
||||
if (this.currentThread != null) {
|
||||
this.currentThread.dead = true;
|
||||
}
|
||||
|
||||
boolean hasPath = !roomUnit.getPath().isEmpty();
|
||||
this.currentThread = new RebugKickBallAction(this, room, roomUnit, hasPath);
|
||||
Emulator.getThreading().run(this.currentThread, 50);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
package com.eu.habbo.threading.runnables;
|
||||
|
||||
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;
|
||||
public boolean dead = false;
|
||||
|
||||
public RebugKickBallAction(HabboItem ball, Room room, RoomUnit kicker, boolean hasPath) {
|
||||
this.ball = ball;
|
||||
this.room = room;
|
||||
this.direction = Direction8.fromDelta(
|
||||
ball.getX() - kicker.getX(),
|
||||
ball.getY() - kicker.getY()
|
||||
);
|
||||
this.momentum = hasPath ? 55 : 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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (this.dead || !this.room.isLoaded()) return;
|
||||
|
||||
try {
|
||||
int nextX = this.ball.getX() + this.direction.getDiffX();
|
||||
int nextY = this.ball.getY() + this.direction.getDiffY();
|
||||
|
||||
if (isTileBlocked(nextX, nextY)) {
|
||||
this.direction = this.direction.rotateDirection180Degrees();
|
||||
nextX = this.ball.getX() + this.direction.getDiffX();
|
||||
nextY = this.ball.getY() + this.direction.getDiffY();
|
||||
}
|
||||
|
||||
RoomTile nextTile = this.room.getLayout().getTile((short) nextX, (short) nextY);
|
||||
if (nextTile == null) 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.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);
|
||||
}
|
||||
|
||||
// Update tiles
|
||||
this.room.updateTile(oldTile);
|
||||
this.room.updateTile(nextTile);
|
||||
|
||||
THashSet<HabboItem> oldItems = this.room.getItemsAt(oldTile);
|
||||
if (oldItems != null && !oldItems.isEmpty()) {
|
||||
oldItems.remove(this.ball);
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
private long getDelayForMomentum(int momentum) {
|
||||
switch (momentum) {
|
||||
case 55: return 100L;
|
||||
case 44: return 100L;
|
||||
case 33: return 200L;
|
||||
case 22: return 250L;
|
||||
case 11: return 500L;
|
||||
default: return 0L;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package com.eu.habbo.util.pathfinding;
|
||||
|
||||
/**
|
||||
* 8-directional movement utility for ball physics.
|
||||
* Ported from the Rebug soccer plugin.
|
||||
*/
|
||||
public class Direction8 {
|
||||
public static final Direction8[] DIRECTIONS = new Direction8[8];
|
||||
|
||||
public static final Direction8 N = new Direction8(0, "N", 0, -1);
|
||||
public static final Direction8 NE = new Direction8(1, "NE", 1, -1);
|
||||
public static final Direction8 E = new Direction8(2, "E", 1, 0);
|
||||
public static final Direction8 SE = new Direction8(3, "SE", 1, 1);
|
||||
public static final Direction8 S = new Direction8(4, "S", 0, 1);
|
||||
public static final Direction8 SW = new Direction8(5, "SW", -1, 1);
|
||||
public static final Direction8 W = new Direction8(6, "W", -1, 0);
|
||||
public static final Direction8 NW = new Direction8(7, "NW", -1, -1);
|
||||
|
||||
private final int rot;
|
||||
private final String rotName;
|
||||
private final int xDiff;
|
||||
private final int yDiff;
|
||||
|
||||
public Direction8(int rot, String rotName, int diffX, int diffY) {
|
||||
this.rot = rot;
|
||||
this.rotName = rotName;
|
||||
this.xDiff = diffX;
|
||||
this.yDiff = diffY;
|
||||
DIRECTIONS[rot] = this;
|
||||
}
|
||||
|
||||
public static Direction8 fromDelta(int deltaX, int deltaY) {
|
||||
if (deltaX == 0) {
|
||||
if (deltaY < 0) return N;
|
||||
if (deltaY > 0) return S;
|
||||
}
|
||||
if (deltaX > 0) {
|
||||
if (deltaY < 0) return NE;
|
||||
if (deltaY == 0) return E;
|
||||
if (deltaY > 0) return SE;
|
||||
}
|
||||
if (deltaX < 0) {
|
||||
if (deltaY < 0) return NW;
|
||||
if (deltaY == 0) return W;
|
||||
if (deltaY > 0) return SW;
|
||||
}
|
||||
return N;
|
||||
}
|
||||
|
||||
public static Direction8 getDirection(int dir) {
|
||||
if (dir < 0 || dir > 7) return N;
|
||||
return DIRECTIONS[dir];
|
||||
}
|
||||
|
||||
public static int validateDirection8Value(int dir) {
|
||||
return dir & 0x7;
|
||||
}
|
||||
|
||||
public int getRot() {
|
||||
return this.rot;
|
||||
}
|
||||
|
||||
public String getRotName() {
|
||||
return this.rotName;
|
||||
}
|
||||
|
||||
public int getDiffX() {
|
||||
return this.xDiff;
|
||||
}
|
||||
|
||||
public int getDiffY() {
|
||||
return this.yDiff;
|
||||
}
|
||||
|
||||
public Direction8 rotateDirection180Degrees() {
|
||||
return getDirectionAtRot(4);
|
||||
}
|
||||
|
||||
public Direction8 rotateDirection90Degrees(boolean clockwise) {
|
||||
return getDirectionAtRot(clockwise ? 2 : -2);
|
||||
}
|
||||
|
||||
public Direction8 rotateDirection45Degrees(boolean clockwise) {
|
||||
return getDirectionAtRot(clockwise ? 1 : -1);
|
||||
}
|
||||
|
||||
public Direction8 getDirectionAtRot(int diff) {
|
||||
return DIRECTIONS[validateDirection8Value(this.rot + diff)];
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.rotName + "(" + this.rot + ")";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user