You've already forked Arcturus-Morningstar-Extended
mirror of
https://github.com/duckietm/Arcturus-Morningstar-Extended.git
synced 2026-06-20 07:26:18 +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.battlebanzai.scoreboards.InteractionBattleBanzaiScoreboardYellow;
|
||||||
import com.eu.habbo.habbohotel.items.interactions.games.football.InteractionFootball;
|
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.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.InteractionFootballGoalBlue;
|
||||||
import com.eu.habbo.habbohotel.items.interactions.games.football.goals.InteractionFootballGoalGreen;
|
import com.eu.habbo.habbohotel.items.interactions.games.football.goals.InteractionFootballGoalGreen;
|
||||||
import com.eu.habbo.habbohotel.items.interactions.games.football.goals.InteractionFootballGoalRed;
|
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("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_gate", InteractionFootballGate.class));
|
||||||
this.interactionsList.add(new ItemInteraction("football_counter_blue", InteractionFootballScoreboardBlue.class));
|
this.interactionsList.add(new ItemInteraction("football_counter_blue", InteractionFootballScoreboardBlue.class));
|
||||||
this.interactionsList.add(new ItemInteraction("football_counter_green", InteractionFootballScoreboardGreen.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